35#ifdef BLOCXX_HAVE_REGEX
36#ifdef BLOCXX_HAVE_REGEX_H
49const int REG_NOERROR = 0;
54substitute_caps(
const PosixRegEx::MatchArray &sub,
57 static const char *cap_refs[] = {
58 NULL,
"\\1",
"\\2",
"\\3",
"\\4",
59 "\\5",
"\\6",
"\\7",
"\\8",
"\\9", NULL
65 for(
size_t i=1; cap_refs[i] != NULL; i++)
69 if( i < sub.size() && sub[i].rm_so >= 0 && sub[i].rm_eo >= 0)
71 cap = str.substring(sub[i].rm_so, sub[i].rm_eo
81 while( at > 0 && res.charAt(--at) ==
'\\')
86 quotes = (quotes + 1) / 2;
88 res = res.erase(pos - quotes, quotes);
90 pos = res.indexOf(cap_refs[i],
97 res = res.substring(0, pos - quotes) +
99 res.substring(pos + 2);
101 pos = res.indexOf(cap_refs[i],
102 pos + cap.length() - quotes);
112getError(
const regex_t *preg,
const int code)
114 char err[256] = {
'\0'};
115 ::regerror(code, preg, err,
sizeof(err));
121PosixRegEx::PosixRegEx()
124 , m_ecode(REG_NOERROR)
130PosixRegEx::PosixRegEx(
const String ®ex,
int cflags)
133 , m_ecode(REG_NOERROR)
135 if( !compile(regex, cflags))
138 errorString().c_str(), m_ecode);
144PosixRegEx::PosixRegEx(
const PosixRegEx &ref)
146 , m_flags(ref.m_flags)
147 , m_ecode(REG_NOERROR)
148 , m_rxstr(ref.m_rxstr)
150 if( ref.compiled && !compile(ref.m_rxstr, ref.m_flags))
152 BLOCXX_THROW_ERR(RegExCompileException,
153 errorString().c_str(), m_ecode);
159PosixRegEx::~PosixRegEx()
170PosixRegEx::operator = (
const PosixRegEx &ref)
174 m_ecode = REG_NOERROR;
176 m_flags = ref.m_flags;
177 m_rxstr = ref.m_rxstr;
184 else if( !compile(ref.m_rxstr, ref.m_flags))
187 errorString().c_str(), m_ecode);
195PosixRegEx::compile(
const String ®ex,
int cflags)
205 m_ecode = ::regcomp(&m_regex, regex.c_str(), cflags);
206 if( m_ecode == REG_NOERROR)
214 m_error = getError(&m_regex, m_ecode);
222PosixRegEx::errorCode()
230PosixRegEx::errorString()
const
238PosixRegEx::patternString()
const
246PosixRegEx::compileFlags()
const
254PosixRegEx::isCompiled()
const
262PosixRegEx::execute(MatchArray &sub,
const String &str,
263 size_t index,
size_t count,
int eflags)
268 "Regular expression is not compiled");
271 if( index > str.length())
274 Format(
"String index out of bounds ("
275 "length = %1, index = %2).",
282 count = m_regex.re_nsub + 1;
284 AutoPtrVec<regmatch_t> rsub(
new regmatch_t[count]);
289 m_ecode = ::regexec(&m_regex, str.c_str() + index,
290 count, rsub.get(), eflags);
291 if( m_ecode == REG_NOERROR)
294 if( m_flags & REG_NOSUB)
300 for(
size_t n = 0; n < count; n++)
302 if( rsub[n].rm_so < 0 || rsub[n].rm_eo < 0)
308 rsub[n].rm_so += index;
309 rsub[n].rm_eo += index;
317 m_error = getError(&m_regex, m_ecode);
325PosixRegEx::capture(
const String &str,
size_t index,
size_t count,
int eflags)
330 "Regular expression is not compiled");
336 bool match = execute(rsub, str, index, count, eflags);
342 "Non-capturing regular expression");
345 MatchArray::const_iterator i=rsub.begin();
346 for( ; i != rsub.end(); ++i)
348 if( i->rm_so >= 0 && i->rm_eo >= 0)
350 ssub.push_back(str.substring(i->rm_so,
351 i->rm_eo - i->rm_so));
355 ssub.push_back(String(
""));
359 else if(m_ecode != REG_NOMATCH)
362 errorString().c_str(), m_ecode);
370PosixRegEx::replace(
const String &str,
const String &rep,
371 bool global,
int eflags)
376 "Regular expression is not compiled");
386 match = execute(rsub, out, off, 0, eflags);
395 "Non-capturing regular expression");
398 String res = substitute_caps(rsub, out, rep);
400 out = out.substring(0, rsub[0].rm_so) +
401 res + out.substring(rsub[0].rm_eo);
403 off = rsub[0].rm_so + res.length();
405 else if(m_ecode == REG_NOMATCH)
407 m_ecode = REG_NOERROR;
413 errorString().c_str(), m_ecode);
415 }
while(global && match && out.length() > off);
422PosixRegEx::split(
const String &str,
bool empty,
int eflags)
427 "Regular expression is not compiled");
434 size_t len = str.length();
438 match = execute(rsub, str, off, 1, eflags);
446 "Non-capturing regular expression");
449 if( empty || ((
size_t)rsub[0].rm_so > off))
451 ssub.push_back(str.substring(off,
452 rsub[0].rm_so - off));
456 else if(m_ecode == REG_NOMATCH)
458 String tmp = str.substring(off);
459 if( empty || !tmp.empty())
463 m_ecode = REG_NOERROR;
469 errorString().c_str(), m_ecode);
471 }
while(match && len > off);
479PosixRegEx::grep(
const StringArray &src,
int eflags)
484 "Regular expression is not compiled");
487 m_ecode = REG_NOERROR;
493 StringArray::const_iterator i=src.begin();
494 for( ; i != src.end(); ++i)
496 int ret = ::regexec(&m_regex, i->c_str(),
498 if( ret == REG_NOERROR)
502 else if(ret != REG_NOMATCH)
505 m_error = getError(&m_regex, m_ecode);
507 errorString().c_str(), m_ecode);
518PosixRegEx::match(
const String &str,
size_t index,
int eflags)
const
523 "Regular expression is not compiled");
526 if( index > str.length())
529 Format(
"String index out of bounds ("
530 "length = %1, index = %2).",
535 m_ecode = ::regexec(&m_regex, str.c_str() + index,
538 if( m_ecode == REG_NOERROR)
543 else if(m_ecode == REG_NOMATCH)
545 m_error = getError(&m_regex, m_ecode);
550 m_error = getError(&m_regex, m_ecode);
552 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