36#ifdef BLOCXX_HAVE_PCRE
37#ifdef BLOCXX_HAVE_PCRE_H
51substitute_caps(
const PerlRegEx::MatchArray &sub,
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
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.
This String class is an abstract data type that represents as NULL terminated string of characters.
size_t indexOf(char ch, size_t fromIndex=0) const
Find the first occurence of a given character in this String object.
Array< String > StringArray