33 #ifndef QUERY_REGEX_HPP_ 34 #define QUERY_REGEX_HPP_ 36 #include "../Main/Exception.hpp" 37 #include "../Wrapper/PCRE.hpp" 38 #include "../Wrapper/PCREMatch.hpp" 81 RegEx(
const std::string& expression,
bool single,
bool multi);
87 [[nodiscard]]
bool getBool(
const std::string& text)
const;
88 void getFirst(
const std::string& text, std::string& resultTo)
const;
89 void getAll(
const std::string& text, std::vector<std::string>& resultTo)
const;
90 [[nodiscard]]
bool valid()
const noexcept;
140 inline RegEx::RegEx(
const std::string& expression,
bool single,
bool multi) {
141 std::string queryString(expression);
142 std::int32_t errorNumber{};
143 PCRE2_SIZE errorOffset{};
146 while(queryString.back() ==
'\n') {
147 queryString.pop_back();
151 if(queryString.empty()) {
155 if(!single && !multi) {
161 this->expressionSingle.
set(
163 static_cast<PCRE2_SPTR>(
164 static_cast<const void *>(
168 PCRE2_ZERO_TERMINATED,
169 PCRE2_UTF | PCRE2_UCP,
176 if(!(this->expressionSingle.
valid())) {
178 std::array<char, pcre2ErrorBufferLength> errorBuffer{};
180 pcre2_get_error_message(
182 static_cast<PCRE2_UCHAR8 *>(
190 std::string exceptionString{
"Compilation error at "};
192 exceptionString += std::to_string(errorOffset);
193 exceptionString +=
": ";
194 exceptionString += errorBuffer.data();
201 this->expressionMulti.
set(
203 static_cast<PCRE2_SPTR>(
204 static_cast<const void *>(
208 PCRE2_ZERO_TERMINATED,
209 PCRE2_UTF | PCRE2_UCP | PCRE2_MULTILINE,
216 if(!(this->expressionMulti.
valid())) {
218 std::array<char, pcre2ErrorBufferLength> errorBuffer{};
220 pcre2_get_error_message(
222 static_cast<PCRE2_UCHAR8 *>(
230 std::string exceptionString{
"Compilation error at "};
232 exceptionString += std::to_string(errorOffset);
233 exceptionString +=
": ";
234 exceptionString += errorBuffer.data();
263 if(!(this->expressionSingle.
valid())) {
269 pcre2_match_data_create_from_pattern(
270 this->expressionSingle.
getc(),
277 this->expressionSingle.
getc(),
278 static_cast<PCRE2_SPTR
>(
279 static_cast<const void *
>(
294 case PCRE2_ERROR_NOMATCH:
304 std::array<char, pcre2ErrorBufferLength> errorBuffer{};
306 pcre2_get_error_message(
308 static_cast<PCRE2_UCHAR8 *>(
350 if(!(this->expressionSingle.
valid())) {
356 pcre2_match_data_create_from_pattern(
357 this->expressionSingle.
getc(),
364 this->expressionSingle.
getc(),
365 static_cast<PCRE2_SPTR
>(
366 static_cast<const void *
>(
381 case PCRE2_ERROR_NOMATCH:
391 std::array<char, pcre2ErrorBufferLength> errorBuffer{};
393 pcre2_get_error_message(
395 static_cast<PCRE2_UCHAR8 *>(
408 auto * pcreOVector{pcre2_get_ovector_pointer(pcreMatch.
get())};
411 resultTo = text.substr(pcreOVector[0], pcreOVector[1] - pcreOVector[0]);
435 inline void RegEx::getAll(
const std::string& text, std::vector<std::string>& resultTo)
const {
440 if(!(this->expressionMulti.
valid())) {
446 pcre2_match_data_create_from_pattern(
447 this->expressionMulti.
getc(),
454 this->expressionMulti.
getc(),
455 static_cast<PCRE2_SPTR
>(
456 static_cast<const void *
>(
471 case PCRE2_ERROR_NOMATCH:
481 std::array<char, pcre2ErrorBufferLength> errorBuffer{};
483 pcre2_get_error_message(
485 static_cast<PCRE2_UCHAR8 *>(
498 auto * pcreOVector{pcre2_get_ovector_pointer(pcreMatch.
get())};
501 resultTo.emplace_back(text, pcreOVector[0], pcreOVector[1] - pcreOVector[0]);
504 std::uint32_t pcreOptions{};
505 std::uint32_t pcreNewLineOption{};
507 pcre2_pattern_info(this->expressionMulti.
getc(), PCRE2_INFO_ALLOPTIONS, &pcreOptions);
508 pcre2_pattern_info(this->expressionMulti.
getc(), PCRE2_INFO_NEWLINE, &pcreNewLineOption);
510 const auto pcreUTF8{(pcreOptions & PCRE2_UTF) != 0};
511 const auto pcreNewLine{
512 pcreNewLineOption == PCRE2_NEWLINE_ANY
513 || pcreNewLineOption == PCRE2_NEWLINE_CRLF
514 || pcreNewLineOption == PCRE2_NEWLINE_ANYCRLF
520 auto pcreOffset{pcreOVector[1]};
525 if(pcreOVector[0] == pcreOVector[1]) {
527 if(pcreOVector[0] == text.length()) {
531 pcreOptions = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
535 result = pcre2_match(
536 this->expressionMulti.
getc(),
537 static_cast<PCRE2_SPTR
>(
538 static_cast<const void *
>(
550 if(result == PCRE2_ERROR_NOMATCH) {
551 if(pcreOptions == 0) {
556 pcreOVector[1] = pcreOffset + 1;
560 && pcreOffset < text.length() - 1
561 && text.at(pcreOffset) ==
'\r' 562 && text.at(pcreOffset + 1) ==
'\n' 569 while(pcreOVector[1] < text.length()) {
585 std::array<char, pcre2ErrorBufferLength> errorBuffer{};
587 pcre2_get_error_message(
589 static_cast<PCRE2_UCHAR8 *>(
606 resultTo.emplace_back(text, pcreOVector[0], pcreOVector[1] - pcreOVector[0]);
616 return this->expressionSingle.
valid() || this->expressionMulti.
valid();
constexpr auto bitmaskTopBit
Bit mask to extract the first bit of a multibyte character.
Definition: RegEx.hpp:60
constexpr auto bitmaskTopTwoBits
Bit mask to extract the top two bits of a multibyte character.
Definition: RegEx.hpp:63
void getFirst(const std::string &text, std::string &resultTo) const
Gets the first match from performing the query on a parsed JSON document.
Definition: RegEx.hpp:345
const pcre2_code * getc() const noexcept
Gets a const pointer to the underlying regular expression.
Definition: PCRE.hpp:160
RAII wrapper for Perl-compatible regular expressions.
Definition: PCRE.hpp:62
Class for JSONPath exceptions.
Definition: RegEx.hpp:108
#define MAIN_EXCEPTION_CLASS()
Macro used to easily define classes for general exceptions.
Definition: Exception.hpp:50
bool valid() const noexcept
Checks whether the underlying regular expression is valid.
Definition: PCRE.hpp:173
void getAll(const std::string &text, std::vector< std::string > &resultTo) const
Gets all matches from performing the query on a parsed JSON document.
Definition: RegEx.hpp:435
constexpr auto pcre2ErrorBufferLength
The length of the error buffer used by the PCRE2 library, in bytes.
Definition: RegEx.hpp:57
Implements a RegEx query using the PCRE2 library.
Definition: RegEx.hpp:76
void set(pcre2_code *regExPtr)
Sets a PERL-compatibe regular expression.
Definition: PCRE.hpp:195
bool valid() const noexcept
Gets whether the query is valid.
Definition: RegEx.hpp:615
RAII wrapper for Perl-compatible regular expression matches.
Definition: PCREMatch.hpp:61
RegEx(const std::string &expression, bool single, bool multi)
Constructor setting a RegEx string and whether the query will return single and/or multiple results...
Definition: RegEx.hpp:140
Namespace for classes handling queries.
Definition: XML.hpp:51
bool getBool(const std::string &text) const
Gets a boolean result from performing the query on a parsed JSON document.
Definition: RegEx.hpp:261
pcre2_match_data * get() noexcept
Gets a pointer to the underlying regular expression match.
Definition: PCREMatch.hpp:140