14 re_pattern_buffer * preg;
20 mutable LRegex::SubMatches matches;
23 Impl(string const & regex)
24 : preg(new re_pattern_buffer), error_code(0)
26 error_code = regcomp(preg, regex.c_str(), REG_EXTENDED);
37 bool exact_match(string const & str) const
40 if (!regexec(preg, str.c_str(), 1, &tmp, 0)) {
42 tmp.rm_eo == static_cast<signed int>(str.length()))
50 LRegex::MatchPair first_match(string const & str) const
53 regexec(preg, str.c_str(), 1, &tmp, 0);
54 unsigned int first = tmp.rm_so != -1 ?
55 static_cast<unsigned int>(tmp.rm_so) : string::npos;
56 unsigned int second = tmp.rm_eo != -1 ?
57 static_cast<unsigned int>(tmp.rm_eo) : string::npos;
58 return make_pair(first, second - first);
62 string getError() const
64 size_t nr = regerror(error_code, preg, 0, 0);
65 char * tmp = new char[nr];
66 regerror(error_code, preg, tmp, nr);
73 LRegex::SubMatches const & exec(string const & str) const
75 // Some room for improvement in this func. I realize
76 // that it is double as expensive as needed, but that
77 // is something I am willing to pay to get the nice
78 // interface. One thing that can be done is to only put
79 // valid submatches into matches. That will not make this
80 // func much faster, but client code will be simpler,
81 // because then it will only be needed to scan through
82 // all the entries in matches.
83 size_t subs = (preg->re_nsub != 0 ? (preg->re_nsub + 1) : 1);
84 regmatch_t * mat = new regmatch_t[subs];
85 unsigned int first = 0;
86 unsigned int second = 0;
87 matches.erase(matches.begin(), matches.end());
88 if (!regexec(preg, str.c_str(), subs, mat, 0)) { // some match
89 matches.reserve(subs);
90 for (size_t i = 0; i < subs; ++i) {
91 first = mat[i].rm_so != -1 ?
92 static_cast<unsigned int>
93 (mat[i].rm_so) : string::npos;
94 second = mat[i].rm_eo != -1 ?
95 static_cast<unsigned int>
96 (mat[i].rm_eo) : string::npos;
97 matches.push_back(make_pair(first,
107 LRegex::LRegex(string const & regex)
108 : impl(new Impl(regex)) {}
117 LRegex::SubMatches const & LRegex::exec(string const & str) const
119 return impl->exec(str);
123 bool LRegex::exact_match(string const & str) const
125 return impl->exact_match(str);
129 LRegex::MatchPair LRegex::first_match(string const & str) const
131 return impl->first_match(str);
135 string LRegex::getError() const
137 return impl->getError();
141 int LRegex::getErrorCode() const
143 return impl->error_code;
147 bool LRegex::ok() const {
148 return impl->error_code == 0;
153 // some built in regular expressions
156 const LRegex LRXwhite("[ \n\t\r\v\f]+");
158 const LRegex LRXint("-?[0-9]+");
160 const LRegex LRXdouble("-?(([0-9]+.[0-9]*)|"
161 "([0-9]+)|(.[0-9]+))"
162 "([eE][---+]?[0-9]+)?");
164 // const LRegex LRXalpha("[A-Za-z]+");
165 // not usable (only ascii)
166 // const LRegex LRXlowercase("[a-z]+");
167 // not usable (only ascii)
168 // const LRegex LRXuppercase("[A-Z]+");
169 // not usable (only ascii)
170 // const LRegex LRXalphanum("[0-9A-Za-z]+");
172 const LRegex LRXidentifier("[A-Za-z_][A-Za-z0-9_]*");