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 -------------------------------------------------------------------------------
10 License
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 
30 inline 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 
42 inline 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 
54 inline bool Foam::regExpCxx::is_meta
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 
96 inline Foam::regExpCxx::regExpCxx(regExpCxx&& rgx) noexcept
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 
133 inline bool Foam::regExpCxx::empty() const noexcept
134 {
135  return !ctrl_;
136 }
137 
138 
139 inline bool Foam::regExpCxx::exists() const noexcept
140 {
141  return ctrl_;
142 }
143 
144 
145 inline bool Foam::regExpCxx::negated() const noexcept
146 {
147  return (ctrl_ == ctrlType::NEGATED);
148 }
149 
150 
151 inline 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 
171 inline 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 
178 inline 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 
209 inline 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 
221 inline 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 
233 Foam::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 
275 inline 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 
289 inline 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 
303 inline bool Foam::regExpCxx::match
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 
322 inline bool Foam::regExpCxx::operator()(const std::string& text) const
323 {
324  return match(text);
325 }
326 
327 
328 inline void Foam::regExpCxx::operator=(const regExpCxx& rgx)
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 
350 inline void Foam::regExpCxx::operator=(const char* pattern)
351 {
352  set(pattern);
353 }
354 
355 
356 inline void Foam::regExpCxx::operator=(const std::string& pattern)
357 {
358  set(pattern);
359 }
360 
361 
362 // ************************************************************************* //
Foam::regExpCxx::ngroups
unsigned ngroups() const
Definition: regExpCxxI.H:171
Foam::BitOps::set
void set(List< bool > &bools, const labelRange &range)
Set the specified range 'on' in a boolList.
Definition: BitOps.C:37
Foam::regExpCxx::find
std::string::size_type find(const std::string &text) const
Find position within the text.
Definition: regExpCxxI.H:233
Foam::regExpCxx::negated
bool negated() const noexcept
True if pattern matching is negated.
Definition: regExpCxxI.H:145
Foam::regExpCxx::operator()
bool operator()(const std::string &text) const
Perform match on text.
Definition: regExpCxxI.H:322
Foam::regExpCxx::set
bool set(const char *pattern, bool ignoreCase=false)
Compile pattern into a regular expression, optionally ignore case.
Definition: regExpCxxI.H:209
Foam::regExpCxx::negate
bool negate(bool on) noexcept
Change pattern negation, return previous value.
Definition: regExpCxxI.H:151
Foam::regExpCxx::match
bool match(const std::string &text) const
True if the regex matches the entire text.
Definition: regExpCxxI.H:289
Foam::regExpCxx::regExpCxx
regExpCxx()
Default construct.
Definition: regExpCxxI.H:82
Foam::regExpCxx::empty
bool empty() const noexcept
True if expression is empty.
Definition: regExpCxxI.H:133
size_type
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:76
Foam::regExpCxx
Wrapper around C++11 regular expressions with some additional prefix-handling. The prefix-handling is...
Definition: regExpCxx.H:82
Foam::regExpCxx::search
bool search(const std::string &text) const
Return true if the regex was found within the text.
Definition: regExpCxxI.H:275
Foam::regExpCxx::clear
bool clear()
Clear expression.
Definition: regExpCxxI.H:184
Foam::stringOps::match
bool match(const UList< wordRe > &patterns, const std::string &text)
Return true if text matches one of the regular expressions.
Definition: stringOps.H:76
clear
patchWriters clear()
Foam::regExpCxx::operator=
void operator=(const regExpCxx &rgx)
Copy assignment.
Definition: regExpCxxI.H:328
Foam::regExpCxx::swap
void swap(regExpCxx &rgx)
Swap contents.
Definition: regExpCxxI.H:198
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Foam::regExpCxx::exists
bool exists() const noexcept
True if expression is non-empty.
Definition: regExpCxxI.H:139
Foam::regExpCxx::is_meta
static bool is_meta(const char c) noexcept
Test if character is a regex meta-character.
Definition: regExpCxxI.H:42
Foam::regExpCxx::nocase
bool nocase() const
Definition: regExpCxxI.H:178
Foam::regExpCxx::grammar
static int grammar
The default grammar (extended | ECMAScript).
Definition: regExpCxx.H:120