35#ifdef BLOCXX_HAVE_REGEX
36#ifdef BLOCXX_HAVE_REGEX_H
49const int REG_NOERROR = 0;
54substitute_caps(
const PosixRegEx::MatchArray &sub,
55 const String &str,
const String &rep)
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
75 pos = res.indexOf(cap_refs[
i]);
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.
Array< String > StringArray