12 #pragma implementation
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 const first_match(string const & str) const
61 regexec(preg, str.c_str(), 1, &tmp, 0);
62 unsigned int const first = tmp.rm_so != -1 ?
63 static_cast<unsigned int>(tmp.rm_so) : string::npos;
64 unsigned int const second = tmp.rm_eo != -1 ?
65 static_cast<unsigned int>(tmp.rm_eo) : string::npos;
66 return make_pair(first, second - first);
70 string const 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);
75 string const ret(tmp);
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.
92 (preg->re_nsub != 0 ? (preg->re_nsub + 1) : 1);
93 regmatch_t * mat = new regmatch_t[subs];
94 unsigned int first = 0;
95 unsigned int second = 0;
96 matches.erase(matches.begin(), matches.end());
97 if (!regexec(preg, str.c_str(), subs, mat, 0)) { // some match
98 matches.reserve(subs);
99 for (size_t i = 0; i < subs; ++i) {
100 first = mat[i].rm_so != -1 ?
101 static_cast<unsigned int>
102 (mat[i].rm_so) : string::npos;
103 second = mat[i].rm_eo != -1 ?
104 static_cast<unsigned int>
105 (mat[i].rm_eo) : string::npos;
106 matches.push_back(make_pair(first,
116 LRegex::LRegex(string const & regex)
117 : impl(new Impl(regex)) {}
126 LRegex::SubMatches const & LRegex::exec(string const & str) const
128 return impl->exec(str);
132 bool LRegex::exact_match(string const & str) const
134 return impl->exact_match(str);
138 LRegex::MatchPair const LRegex::first_match(string const & str) const
140 return impl->first_match(str);
144 string const LRegex::getError() const
146 return impl->getError();
150 int LRegex::getErrorCode() const
152 return impl->error_code;
156 bool LRegex::ok() const {
157 return impl->error_code == 0;
162 // some built in regular expressions
165 const LRegex LRXwhite("[ \n\t\r\v\f]+");
167 const LRegex LRXint("-?[0-9]+");
169 const LRegex LRXdouble("-?(([0-9]+.[0-9]*)|"
170 "([0-9]+)|(.[0-9]+))"
171 "([eE][---+]?[0-9]+)?");
173 // const LRegex LRXalpha("[A-Za-z]+");
174 // not usable (only ascii)
175 // const LRegex LRXlowercase("[a-z]+");
176 // not usable (only ascii)
177 // const LRegex LRXuppercase("[A-Z]+");
178 // not usable (only ascii)
179 // const LRegex LRXalphanum("[0-9A-Za-z]+");
181 const LRegex LRXidentifier("[A-Za-z_][A-Za-z0-9_]*");