22 mutable LRegex::SubMatches matches;
25 Impl(string const & regex)
26 : preg(new regex_t), error_code(0)
28 error_code = regcomp(preg, regex.c_str(), REG_EXTENDED);
39 bool exact_match(string const & str) const
42 if (!regexec(preg, str.c_str(), 1, &tmp, 0)) {
44 tmp.rm_eo == static_cast<signed int>(str.length()))
52 LRegex::MatchPair first_match(string const & str) const
55 regexec(preg, str.c_str(), 1, &tmp, 0);
56 unsigned int first = tmp.rm_so != -1 ?
57 static_cast<unsigned int>(tmp.rm_so) : string::npos;
58 unsigned int second = tmp.rm_eo != -1 ?
59 static_cast<unsigned int>(tmp.rm_eo) : string::npos;
60 return make_pair(first, second - first);
64 string getError() const
66 size_t nr = regerror(error_code, preg, 0, 0);
67 char * tmp = new char[nr];
68 regerror(error_code, preg, tmp, nr);
75 LRegex::SubMatches const & exec(string const & str) const
77 // Some room for improvement in this func. I realize
78 // that it is double as expensive as needed, but that
79 // is something I am willing to pay to get the nice
80 // interface. One thing that can be done is to only put
81 // valid submatches into matches. That will not make this
82 // func much faster, but client code will be simpler,
83 // because then it will only be needed to scan through
84 // all the entries in matches.
85 size_t subs = (preg->re_nsub != 0 ? (preg->re_nsub + 1) : 1);
86 regmatch_t * mat = new regmatch_t[subs];
87 unsigned int first = 0;
88 unsigned int second = 0;
89 matches.erase(matches.begin(), matches.end());
90 if (!regexec(preg, str.c_str(), subs, mat, 0)) { // some match
91 matches.reserve(subs);
92 for (size_t i = 0; i < subs; ++i) {
93 first = mat[i].rm_so != -1 ?
94 static_cast<unsigned int>
95 (mat[i].rm_so) : string::npos;
96 second = mat[i].rm_eo != -1 ?
97 static_cast<unsigned int>
98 (mat[i].rm_eo) : string::npos;
99 matches.push_back(make_pair(first,
109 LRegex::LRegex(string const & regex)
110 : impl(new Impl(regex)) {}
119 LRegex::SubMatches const & LRegex::exec(string const & str) const
121 return impl->exec(str);
125 bool LRegex::exact_match(string const & str) const
127 return impl->exact_match(str);
131 LRegex::MatchPair LRegex::first_match(string const & str) const
133 return impl->first_match(str);
137 string LRegex::getError() const
139 return impl->getError();
143 int LRegex::getErrorCode() const
145 return impl->error_code;
149 bool LRegex::ok() const {
150 return impl->error_code == 0;
155 // some built in regular expressions
158 const LRegex LRXwhite("[ \n\t\r\v\f]+");
160 const LRegex LRXint("-?[0-9]+");
162 const LRegex LRXdouble("-?(([0-9]+.[0-9]*)|"
163 "([0-9]+)|(.[0-9]+))"
164 "([eE][---+]?[0-9]+)?");
166 // const LRegex LRXalpha("[A-Za-z]+");
167 // not usable (only ascii)
168 // const LRegex LRXlowercase("[a-z]+");
169 // not usable (only ascii)
170 // const LRegex LRXuppercase("[A-Z]+");
171 // not usable (only ascii)
172 // const LRegex LRXalphanum("[0-9A-Za-z]+");
174 const LRegex LRXidentifier("[A-Za-z_][A-Za-z0-9_]*");