36#ifdef BLOCXX_HAVE_PCRE
37#ifdef BLOCXX_HAVE_PCRE_H
51substitute_caps(
const PerlRegEx::MatchArray &sub,
52 const String &str,
const String &rep)
54 static const char *cap_refs[] = {
55 NULL,
"\\1",
"\\2",
"\\3",
"\\4",
56 "\\5",
"\\6",
"\\7",
"\\8",
"\\9", NULL
62 for(
size_t i=1; cap_refs[
i] != NULL;
i++)
65 if(
i < sub.size() && sub[
i].rm_so >= 0 && sub[
i].rm_eo >= 0)
67 cap = str.substring(sub[
i].rm_so, sub[
i].rm_eo
71 pos = res.indexOf(cap_refs[
i]);
77 while( at > 0 && res.charAt(--at) ==
'\\')
82 quotes = (quotes + 1) / 2;
84 res = res.erase(pos - quotes, quotes);
86 pos = res.indexOf(cap_refs[
i],
93 res = res.substring(0, pos - quotes) +
95 res.substring(pos + 2);
97 pos = res.indexOf(cap_refs[
i],
98 pos + cap.length() - quotes);
108getError(
const int errcode)
114 ptr =
"match vector to small";
117 case PCRE_ERROR_NOMATCH:
118 ptr =
"match failed";
121 case PCRE_ERROR_NULL:
122 ptr =
"invalid argument";
125 case PCRE_ERROR_BADOPTION:
126 ptr =
"unrecognized option";
129 case PCRE_ERROR_BADMAGIC:
130 ptr =
"invalid magic number";
133 case PCRE_ERROR_UNKNOWN_NODE:
134 ptr =
"unknown item in the compiled pattern";
137 case PCRE_ERROR_NOMEMORY:
138 ptr =
"failed to allocate memory";
141 case PCRE_ERROR_NOSUBSTRING:
143 ptr =
"failed to retrieve substring";
146 case PCRE_ERROR_MATCHLIMIT:
148 ptr =
"recursion or backtracking limit reached";
151 case PCRE_ERROR_CALLOUT:
153 ptr =
"callout failure";
156 case PCRE_ERROR_BADUTF8:
157 ptr =
"invalid UTF-8 byte sequence found";
160 case PCRE_ERROR_BADUTF8_OFFSET:
161 ptr =
"not a UTF-8 character at specified index";
164 case PCRE_ERROR_PARTIAL:
165 ptr =
"partial match";
168 case PCRE_ERROR_BADPARTIAL:
169 ptr =
"pattern item not supported for partial matching";
172 case PCRE_ERROR_INTERNAL:
173 ptr =
"unexpected internal error occurred";
176 case PCRE_ERROR_BADCOUNT:
177 ptr =
"invalid (negative) match vector count";
181 ptr =
"unknown error code";
188PerlRegEx::PerlRegEx()
197PerlRegEx::PerlRegEx(
const String ®ex,
int cflags)
202 if( !compile(regex, cflags))
205 errorString().c_str(), m_ecode);
211PerlRegEx::PerlRegEx(
const PerlRegEx &ref)
213 , m_flags(ref.m_flags)
215 , m_rxstr(ref.m_rxstr)
217 if( ref.m_pcre != NULL && !compile(ref.m_rxstr, ref.m_flags))
219 BLOCXX_THROW_ERR(RegExCompileException,
220 errorString().c_str(), m_ecode);
225PerlRegEx::~PerlRegEx()
237PerlRegEx::operator = (
const PerlRegEx &ref)
239 if( ref.m_pcre == NULL)
243 m_flags = ref.m_flags;
244 m_rxstr = ref.m_rxstr;
251 else if( !compile(ref.m_rxstr, ref.m_flags))
254 errorString().c_str(), m_ecode);
262PerlRegEx::compile(
const String ®ex,
int cflags)
270 const char *errptr = NULL;
273 m_pcre = ::pcre_compile(regex.c_str(), cflags,
274 &errptr, &m_ecode, NULL);
277 m_error = String(errptr ? errptr :
"");
294PerlRegEx::errorCode()
302PerlRegEx::errorString()
const
310PerlRegEx::patternString()
const
318PerlRegEx::compileFlags()
const
326PerlRegEx::isCompiled()
const
328 return (m_pcre != NULL);
334PerlRegEx::execute(MatchArray &sub,
const String &str,
335 size_t index,
size_t count,
int eflags)
340 "Regular expression is not compiled");
342 if( count >=
size_t(INT_MAX / 3))
345 "Match count limit exceeded");
348 if( index > str.length())
351 Format(
"String index out of bounds ("
352 "length = %1, index = %2).",
360 int ret = ::pcre_fullinfo(m_pcre, NULL,
361 PCRE_INFO_CAPTURECOUNT, &cnt);
364 m_error = getError(m_ecode);
367 count = cnt > 0 ? cnt + 1 : 1;
372 m_ecode = ::pcre_exec(m_pcre, NULL, str.c_str(), str.length(),
373 index, eflags, vsub, count * 3);
381 for(
size_t i = 0, n = 0;
i < count;
i++, n += 2)
383 match_t m = { vsub[n], vsub[n+1] };
386 if(
i >= (
size_t)m_ecode)
387 m.rm_so = m.rm_eo = -1;
396 m_error = getError(m_ecode);
404PerlRegEx::execute(MatchVector &sub,
const String &str,
405 size_t index,
size_t count,
int eflags)
410 "Regular expression is not compiled");
412 if( count >=
size_t(INT_MAX / 3))
415 "Match count limit exceeded");
418 if( index > str.length())
421 Format(
"String index out of bounds ("
422 "length = %1, index = %2)",
430 int ret = ::pcre_fullinfo(m_pcre, NULL,
431 PCRE_INFO_CAPTURECOUNT, &cnt);
434 m_error = getError(m_ecode);
437 count = cnt > 0 ? cnt + 1 : 1;
442 m_ecode = ::pcre_exec(m_pcre, NULL, str.c_str(), str.length(),
443 index, eflags, vsub, count * 3);
453 for(
size_t i = 0;
i < count;
i++)
456 if(
i >= (
size_t)m_ecode)
465 m_error = getError(m_ecode);
473PerlRegEx::capture(
const String &str,
size_t index,
size_t count,
int eflags)
478 "Regular expression is not compiled");
484 bool match = execute(rsub, str, index, count, eflags);
490 "Non-capturing regular expression");
493 MatchArray::const_iterator
i=rsub.begin();
494 for( ;
i != rsub.end(); ++
i)
496 if(
i->rm_so >= 0 &&
i->rm_eo >= 0)
498 ssub.push_back(str.substring(
i->rm_so,
499 i->rm_eo -
i->rm_so));
503 ssub.push_back(String(
""));
507 else if(m_ecode != PCRE_ERROR_NOMATCH)
510 errorString().c_str(), m_ecode);
518PerlRegEx::replace(
const String &str,
const String &rep,
519 bool global,
int eflags)
524 "Regular expression is not compiled");
534 match = execute(rsub, out, off, 0, eflags);
543 "Non-capturing regular expression");
546 String res = substitute_caps(rsub, out, rep);
548 out = out.substring(0, rsub[0].rm_so) +
549 res + out.substring(rsub[0].rm_eo);
551 off = rsub[0].rm_so + res.length();
553 else if(m_ecode == PCRE_ERROR_NOMATCH)
561 errorString().c_str(), m_ecode);
563 }
while(global && match && out.length() > off);
571PerlRegEx::split(
const String &str,
bool empty,
int eflags)
576 "Regular expression is not compiled");
583 size_t len = str.length();
587 match = execute(rsub, str, off, 0, eflags);
595 "Non-capturing regular expression");
598 if( empty || ((
size_t)rsub[0].rm_so > off))
600 ssub.push_back(str.substring(off,
601 rsub[0].rm_so - off));
605 else if(m_ecode == PCRE_ERROR_NOMATCH)
607 String tmp = str.substring(off);
608 if( empty || !tmp.empty())
618 errorString().c_str(), m_ecode);
620 }
while(match && len > off);
628PerlRegEx::grep(
const StringArray &src,
int eflags)
633 "Regular expression is not compiled");
642 StringArray::const_iterator
i=src.begin();
643 for( ;
i != src.end(); ++
i)
645 int ret = ::pcre_exec(m_pcre, NULL,
i->c_str(),
646 i->length(), 0, eflags, NULL, 0);
651 else if( ret != PCRE_ERROR_NOMATCH)
654 m_error = getError(m_ecode);
656 errorString().c_str(), m_ecode);
666PerlRegEx::match(
const String &str,
size_t index,
int eflags)
const
671 "Regular expression is not compiled");
674 if( index > str.length())
677 Format(
"String index out of bounds."
678 "length = %1, index = %2",
683 m_ecode = ::pcre_exec(m_pcre, NULL, str.c_str(),
684 str.length(), 0, eflags, NULL, 0);
690 else if( m_ecode == PCRE_ERROR_NOMATCH)
692 m_error = getError(m_ecode);
697 m_error = getError(m_ecode);
699 errorString().c_str(), m_ecode);
#define BLOCXX_THROW(exType, msg)
Throw an exception using FILE and LINE.
#define BLOCXX_THROW_ERR(exType, msg, err)
Throw an exception using FILE and LINE.
iterator erase(iterator position)
Remove an element of the Array specified with an iterator.
Array< String > StringArray