regExpCxxI.H
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2017-2021 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
29
30inline std::regex::flag_type Foam::regExpCxx::syntax()
31{
32 // 0 = extended, 1 = ECMAScript
33 return
34 (
36 ? std::regex::ECMAScript
37 : std::regex::extended
38 );
39}
40
41
42inline bool Foam::regExpCxx::is_meta(const char c) noexcept
43{
44 return
45 (
46 (c == '.') // any character
47 || (c == '*' || c == '+' || c == '?') // quantifiers
48 || (c == '(' || c == ')' || c == '|') // grouping/branching
49 || (c == '[' || c == ']') // range
50 );
51}
52
53
55(
56 const std::string& str,
57 const char quote
58)
59{
60 bool escaped = false;
61 for (const char c : str)
62 {
63 if (quote && c == quote)
64 {
65 escaped = !escaped; // toggle state
66 }
67 else if (escaped)
68 {
69 escaped = false;
70 }
71 else if (is_meta(c))
72 {
73 return true;
74 }
75 }
76 return false;
77}
78
79
80// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
81
83:
84 re_(),
85 ctrl_(0)
86{}
87
88
90:
91 re_(rgx.re_),
92 ctrl_(rgx.ctrl_)
93{}
94
95
97:
98 re_(std::move(rgx.re_)),
99 ctrl_(rgx.ctrl_)
100{
101 rgx.ctrl_ = 0;
102}
103
104
106(
107 const char* pattern,
108 const bool ignoreCase
109)
110:
111 re_(),
112 ctrl_(0)
113{
114 set(pattern, ignoreCase);
115}
116
117
119(
120 const std::string& pattern,
121 const bool ignoreCase
122)
123:
124 re_(),
125 ctrl_(0)
126{
127 set(pattern, ignoreCase);
128}
129
130
131// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
132
134{
135 return !ctrl_;
136}
137
138
140{
141 return ctrl_;
142}
143
144
146{
147 return (ctrl_ == ctrlType::NEGATED);
148}
149
150
151inline bool Foam::regExpCxx::negate(bool on) noexcept
152{
153 bool old(ctrl_ == ctrlType::NEGATED);
154
155 if (on)
156 {
157 if (ctrl_)
158 {
159 ctrl_ = ctrlType::NEGATED;
160 }
161 }
162 else if (old)
163 {
164 ctrl_ = ctrlType::NORMAL;
165 }
166
167 return old;
168}
169
170
171inline unsigned Foam::regExpCxx::ngroups() const
172{
173 // Groups only make sense for regular (not negated) matching
174 return ctrl_ == ctrlType::NORMAL ? re_.mark_count() : 0;
175}
176
177
178inline bool Foam::regExpCxx::nocase() const
179{
180 return ctrl_ && ((re_.flags() & std::regex::icase) == std::regex::icase);
181}
182
183
185{
186 if (ctrl_)
187 {
188 re_.assign("");
189 ctrl_ = 0;
190
191 return true;
192 }
193
194 return false;
195}
196
197
199{
200 if (this != &rgx)
201 {
202 // Self-swap is a no-op
203 re_.swap(rgx.re_);
204 std::swap(ctrl_, rgx.ctrl_);
205 }
206}
207
208
209inline bool Foam::regExpCxx::set(const char* pattern, bool ignoreCase)
210{
211 // Silently handle nullptr
212 return set_pattern
213 (
214 pattern,
215 (pattern ? std::char_traits<char>::length(pattern) : 0),
216 ignoreCase
217 );
218}
219
220
221inline bool Foam::regExpCxx::set(const std::string& pattern, bool ignoreCase)
222{
223 return set_pattern
224 (
225 pattern.data(),
226 pattern.length(),
227 ignoreCase
228 );
229}
230
231
232inline std::string::size_type
233Foam::regExpCxx::find(const std::string& text) const
234{
235 // Find with negated is probably not very reliable...
236 if (!ctrl_)
237 {
238 // Undefined: never matches
239 return std::string::npos;
240 }
241 else if (text.empty())
242 {
243 if (ctrl_ == ctrlType::NEGATED)
244 {
245 return 0; // No match - pretend it starts at position 0
246 }
247 else
248 {
249 return std::string::npos;
250 }
251 }
252 else
253 {
254 std::smatch mat;
255
256 const bool ok = std::regex_search(text, mat, re_);
257
258 if (ctrl_ == ctrlType::NEGATED)
259 {
260 if (!ok)
261 {
262 return 0; // No match - claim that is starts at position 0
263 }
264 }
265 else if (ok)
266 {
267 return mat.position(0);
268 }
269 }
270
271 return std::string::npos; // False
272}
273
274
275inline bool Foam::regExpCxx::search(const std::string& text) const
276{
277 if (!ctrl_)
278 {
279 // Undefined: never matches
280 return false;
281 }
282
283 const bool ok = (!text.empty() && std::regex_search(text, re_));
284
285 return (ctrl_ == ctrlType::NEGATED) ? !ok : ok;
286}
287
288
289inline bool Foam::regExpCxx::match(const std::string& text) const
290{
291 if (!ctrl_)
292 {
293 // Undefined: never matches
294 return false;
295 }
296
297 const bool ok = (!text.empty() && std::regex_match(text, re_));
298
299 return (ctrl_ == ctrlType::NEGATED) ? !ok : ok;
300}
301
302
304(
305 const std::string& text,
306 std::smatch& matches
307) const
308{
309 // Probably does not make sense for negated pattern...
310 if (negated())
311 {
312 // clear: matches = std::smatch();
313 return match(text);
314 }
315
316 return std::regex_match(text, matches, re_);
317}
318
319
320// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
321
322inline bool Foam::regExpCxx::operator()(const std::string& text) const
323{
324 return match(text);
325}
326
327
329{
330 if (this != &rgx)
331 {
332 // Self-assignment is a no-op
333 re_ = rgx.re_;
334 ctrl_ = rgx.ctrl_;
335 }
336}
337
338
340{
341 if (this != &rgx)
342 {
343 // Self-assignment is a no-op
344 clear();
345 swap(rgx);
346 }
347}
348
349
350inline void Foam::regExpCxx::operator=(const char* pattern)
351{
352 set(pattern);
353}
354
355
356inline void Foam::regExpCxx::operator=(const std::string& pattern)
357{
358 set(pattern);
359}
360
361
362// ************************************************************************* //
Ostream & operator()() const
Output stream (master only).
Definition: ensightCaseI.H:74
void negate()
Inplace negate.
Definition: faMatrix.C:800
Wrapper around C++11 regular expressions with some additional prefix-handling. The prefix-handling is...
Definition: regExpCxx.H:83
bool nocase() const
Definition: regExpCxxI.H:178
bool empty() const noexcept
True if expression is empty.
Definition: regExpCxxI.H:133
regExpCxx()
Default construct.
Definition: regExpCxxI.H:82
std::string::size_type find(const std::string &text) const
Find position within the text.
Definition: regExpCxxI.H:233
bool set(const char *pattern, bool ignoreCase=false)
Compile pattern into a regular expression, optionally ignore case.
Definition: regExpCxxI.H:209
bool exists() const noexcept
True if expression is non-empty.
Definition: regExpCxxI.H:139
void operator=(const regExpCxx &rgx)
Copy assignment.
Definition: regExpCxxI.H:328
bool match(const std::string &text) const
True if the regex matches the entire text.
Definition: regExpCxxI.H:289
bool search(const std::string &text) const
Return true if the regex was found within the text.
Definition: regExpCxxI.H:275
bool negated() const noexcept
True if pattern matching is negated.
Definition: regExpCxxI.H:145
bool clear()
Clear expression.
Definition: regExpCxxI.H:184
static bool is_meta(const char c) noexcept
Test if character is a regex meta-character.
Definition: regExpCxxI.H:42
void swap(regExpCxx &rgx)
Swap contents.
Definition: regExpCxxI.H:198
static int grammar
The default grammar (extended | ECMAScript).
Definition: regExpCxx.H:120
unsigned ngroups() const
Definition: regExpCxxI.H:171
bool set() const
Are all the vector set.
Definition: triadI.H:76
patchWriters clear()
const direction noexcept
Definition: Scalar.H:223