Files
openfoam/src/OpenFOAM/primitives/strings/regex/regExpCxx.H
Mark Olesen 6a87dbcbcd ENH: encapsulate wordRe regex with pointer
- reduces overall size and other overhead when wordRe represents
  a literal.
2022-01-31 20:08:52 +01:00

290 lines
8.5 KiB
C++

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::regExpCxx
Description
Wrapper around C++11 regular expressions
with some additional prefix-handling. The prefix-handling is loosely
oriented on PCRE regular expressions and provides a simple means of
tuning the expressions.
The prefixes are detected as \c (?...) at the beginning of
the regular expression. Any unknown/unsupported prefixes are silently
ignored.
- "(?!i)" :
one or more embedded pattern-match modifiers for the entire pattern.
- the \c 'i' indicates ignore-case
- the \c '!' (exclamation) indicates negated (inverted) matching
.
Note
Uses either POSIX extended regular expressions or
<a href=
"http://www.cplusplus.com/reference/regex/ECMAScript"
>modified ECMAScript regular expression grammar</a>
Since ECMAScript grammar may not work correctly on all installations,
the current default is to use extended regular expressions.
The C++11 regular expressions may be broken on some compilers.
For example, gcc 4.8 is known to fail.
For these systems the POSIX implementation or alternative must be used.
Warning
This class should not be used directly.
Use the Foam::regExp typedef instead.
SourceFiles
regExpCxx.C
regExpCxxI.H
\*---------------------------------------------------------------------------*/
#ifndef Foam_regExpCxx_H
#define Foam_regExpCxx_H
#include <regex>
#include <string>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class regExpCxx Declaration
\*---------------------------------------------------------------------------*/
class regExpCxx
{
// Data Types
//- Simple control types
enum ctrlType { EMPTY = 0, NORMAL = 1, NEGATED = 2 };
// Private Data
//- Regular expression (using char type)
std::regex re_;
//- Track if input pattern is non-empty, negated etc.
unsigned char ctrl_;
// Private Member Functions
//- Select grammar based on regExpCxx optimisationSwitch
// 0 = extended, 1 = ECMAScript
static inline std::regex::flag_type syntax();
//- Assign pattern
bool set_pattern(const char* pattern, size_t len, bool ignoreCase);
public:
// Public Types
//- Type for matches
typedef std::smatch results_type;
// Static Member Data
//- The default grammar (extended | ECMAScript).
static int grammar;
// Static Member Functions
//- Test if character is a regex meta-character
// \return True if character is one of the following:
// - any character: '.' \n
// - quantifiers: '*', '+', '?' \n
// - grouping: '(', '|', ')' \n
// - range: '[', ']' \n
//
// \note Regex bounds '{', '}' are not considered
inline static bool is_meta(const char c) noexcept;
//- Test if string contains any (unquoted) meta-characters
inline static bool is_meta
(
const std::string& str,
const char quote = '\\'
);
// Public Classes
//- Functor wrapper for testing meta-characters
struct meta
{
//- Test if character is a regex meta-character
bool operator()(const char c) const noexcept
{
return is_meta(c);
}
//- Test string for meta-characters
bool operator()(const std::string& s, const char q = '\\') const
{
return is_meta(s, q);
}
};
// Constructors
//- Default construct
inline regExpCxx();
//- Copy construct
inline regExpCxx(const regExpCxx& rgx);
//- Move construct
inline regExpCxx(regExpCxx&& rgx) noexcept;
//- Construct from character array, optionally ignore case
inline explicit regExpCxx
(
const char* pattern,
const bool ignoreCase = false
);
//- Construct from string, optionally ignore case
inline explicit regExpCxx
(
const std::string& pattern,
const bool ignoreCase = false
);
//- Destructor
~regExpCxx() = default;
// Member Functions
// Access
//- True if expression is empty
inline bool empty() const noexcept;
//- True if expression is non-empty
inline bool exists() const noexcept;
//- True if pattern matching is negated
inline bool negated() const noexcept;
//- Change pattern negation, return previous value
inline bool negate(bool on) noexcept;
//- The number of capture groups for a non-empty,
//- non-negated expressions
inline unsigned ngroups() const;
// \return True if the pattern was set with ignore-case.
inline bool nocase() const;
// Editing
//- Clear expression.
// \return True if expression had existed prior to the clear.
inline bool clear();
//- Swap contents
inline void swap(regExpCxx& rgx);
//- Compile pattern into a regular expression, optionally ignore case.
// \return True if the pattern was compiled
inline bool set(const char* pattern, bool ignoreCase=false);
//- Compile pattern into a regular expression, optionally ignore case.
// \return True if the pattern was compiled
inline bool set(const std::string& pattern, bool ignoreCase=false);
// Matching/Searching
//- Find position within the text.
// \return The index where it begins or string::npos if not found
//
// \note does not properly work with negated regex!
inline std::string::size_type find(const std::string& text) const;
//- True if the regex matches the entire text.
// The begin-of-line (^) and end-of-line ($) anchors are implicit
inline bool match(const std::string& text) const;
//- True if the regex matches the text, set the matches.
// The first group starts at index 1 (0 is the entire match).
// The begin-of-line (^) and end-of-line ($) anchors are implicit
//
// \note does not properly work with negated regex!
inline bool match(const std::string& text, results_type& matches) const;
//- Return true if the regex was found within the text
inline bool search(const std::string& text) const;
// Member Operators
//- Perform match on text
inline bool operator()(const std::string& text) const;
//- Copy assignment
inline void operator=(const regExpCxx& rgx);
//- Move assignment
inline void operator=(regExpCxx&& rgx);
//- Assign and compile pattern from a character array.
// Matching is case sensitive.
inline void operator=(const char* pattern);
//- Assign and compile pattern from string.
// Matching is case sensitive.
inline void operator=(const std::string& pattern);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "regExpCxxI.H"
#endif
// ************************************************************************* //