28 mutable LRegex::SubMatches matches;
31 Impl(string const & regex)
32 : preg(new regex_t), error_code(0)
34 error_code = regcomp(preg, regex.c_str(), REG_EXTENDED);
45 bool exact_match(string const & str) const
48 if (!regexec(preg, str.c_str(), 1, &tmp, 0)) {
50 tmp.rm_eo == static_cast<signed int>(str.length()))
58 LRegex::MatchPair first_match(string const & str) const
61 regexec(preg, str.c_str(), 1, &tmp, 0);
62 unsigned int first = tmp.rm_so != -1 ?
63 static_cast<unsigned int>(tmp.rm_so) : string::npos;
64 unsigned int second = tmp.rm_eo != -1 ?
65 static_cast<unsigned int>(tmp.rm_eo) : string::npos;
66 return make_pair(first, second - first);
70 string getError() const
72 size_t nr = regerror(error_code, preg, 0, 0);
73 char * tmp = new char[nr];
74 regerror(error_code, preg, tmp, nr);
81 LRegex::SubMatches const & exec(string const & str) const
83 // Some room for improvement in this func. I realize
84 // that it is double as expensive as needed, but that
85 // is something I am willing to pay to get the nice
86 // interface. One thing that can be done is to only put
87 // valid submatches into matches. That will not make this
88 // func much faster, but client code will be simpler,
89 // because then it will only be needed to scan through
90 // all the entries in matches.
91 size_t subs = (preg->re_nsub != 0 ? (preg->re_nsub + 1) : 1);
92 regmatch_t * mat = new regmatch_t[subs];
93 unsigned int first = 0;
94 unsigned int second = 0;
95 matches.erase(matches.begin(), matches.end());
96 if (!regexec(preg, str.c_str(), subs, mat, 0)) { // some match
97 matches.reserve(subs);
98 for (size_t i = 0; i < subs; ++i) {
99 first = mat[i].rm_so != -1 ?
100 static_cast<unsigned int>
101 (mat[i].rm_so) : string::npos;
102 second = mat[i].rm_eo != -1 ?
103 static_cast<unsigned int>
104 (mat[i].rm_eo) : string::npos;
105 matches.push_back(make_pair(first,
115 LRegex::LRegex(string const & regex)
116 : impl(new Impl(regex)) {}
125 LRegex::SubMatches const & LRegex::exec(string const & str) const
127 return impl->exec(str);
131 bool LRegex::exact_match(string const & str) const
133 return impl->exact_match(str);
137 LRegex::MatchPair LRegex::first_match(string const & str) const
139 return impl->first_match(str);
143 string LRegex::getError() const
145 return impl->getError();
149 int LRegex::getErrorCode() const
151 return impl->error_code;
155 bool LRegex::ok() const {
156 return impl->error_code == 0;
161 // some built in regular expressions
164 const LRegex LRXwhite("[ \n\t\r\v\f]+");
166 const LRegex LRXint("-?[0-9]+");
168 const LRegex LRXdouble("-?(([0-9]+.[0-9]*)|"
169 "([0-9]+)|(.[0-9]+))"
170 "([eE][---+]?[0-9]+)?");
172 // const LRegex LRXalpha("[A-Za-z]+");
173 // not usable (only ascii)
174 // const LRegex LRXlowercase("[a-z]+");
175 // not usable (only ascii)
176 // const LRegex LRXuppercase("[A-Z]+");
177 // not usable (only ascii)
178 // const LRegex LRXalphanum("[0-9A-Za-z]+");
180 const LRegex LRXidentifier("[A-Za-z_][A-Za-z0-9_]*");