diff --git a/.gitignore b/.gitignore index 75596d3e688..d909c1b0216 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,4 @@ eclcc.log ./dockerfiles/platform-build-incremental/hpcc.gitpatch dockerfiles/platform-build-incremental/hpcc.gitpatch .env -/vcpkg.json +/vcpkg.json \ No newline at end of file diff --git a/cmake_modules/commonSetup.cmake b/cmake_modules/commonSetup.cmake index 36608e3fc59..b62d4cc6905 100644 --- a/cmake_modules/commonSetup.cmake +++ b/cmake_modules/commonSetup.cmake @@ -839,11 +839,6 @@ IF ("${COMMONSETUP_DONE}" STREQUAL "") endif() endif(USE_URIPARSER) - find_package(Boost COMPONENTS regex) - if (NOT Boost_REGEX_FOUND) - message(FATAL_ERROR "BOOST_REGEX required but package not found") - endif() - if(USE_PARQUET) message(STATUS "Parquet enabled") add_definitions(-D_USE_PARQUET) diff --git a/cmake_modules/options.cmake b/cmake_modules/options.cmake index c40809f97bb..58fe7cc1057 100644 --- a/cmake_modules/options.cmake +++ b/cmake_modules/options.cmake @@ -17,7 +17,6 @@ option(SIGN_MODULES "Enable signing of ecl standard library modules" OFF) option(USE_CPPUNIT "Enable unit tests (requires cppunit)" OFF) option(USE_OPENLDAP "Enable OpenLDAP support (requires OpenLDAP)" ON) option(USE_ICU "Enable unicode support (requires ICU)" ON) -option(Boost_USE_STATIC_LIBS "Use boost_regex static library for RPM BUILD" OFF) option(USE_OPENSSL "Configure use of OpenSSL" ON) option(USE_OPENSSLV3 "Configure use of OpenSSL Version 3 or newer" ON) option(USE_ZLIB "Configure use of zlib" ON) diff --git a/rtl/eclrtl/CMakeLists.txt b/rtl/eclrtl/CMakeLists.txt index b097e1fbcc4..1b10505dcfd 100644 --- a/rtl/eclrtl/CMakeLists.txt +++ b/rtl/eclrtl/CMakeLists.txt @@ -76,7 +76,6 @@ include_directories ( ./../../system/jlib ./../../roxie/roxiemem ./../../testing/unittests - ${Boost_INCLUDE_DIRS} ) ADD_DEFINITIONS( -D_USRDLL -DECLRTL_EXPORTS ) @@ -87,7 +86,8 @@ endif () HPCC_ADD_LIBRARY( eclrtl SHARED ${SRCS} ) -target_link_libraries( eclrtl Boost::boost Boost::regex ) +find_package(pcre2 CONFIG REQUIRED) +target_link_libraries( eclrtl PCRE2::8BIT PCRE2::16BIT ) target_link_libraries ( eclrtl jlib diff --git a/rtl/eclrtl/eclregex.cpp b/rtl/eclrtl/eclregex.cpp index 75362531721..08aa457a94b 100644 --- a/rtl/eclrtl/eclregex.cpp +++ b/rtl/eclrtl/eclregex.cpp @@ -16,67 +16,124 @@ ############################################################################## */ #include "limits.h" -#include "boost/regex.hpp" // must precede platform.h ; n.b. this uses a #pragma comment(lib, ...) to link the appropriate .lib in MSVC + +// PCRE2_CODE_UNIT_WIDTH must be defined before the pcre.h include; +// set PCRE2_CODE_UNIT_WIDTH to zero (meaning, no default char bit width) +// so we can freely switch between 8 and 16 bits (STRING and UTF-8 support for +// the former, UNICODE support for the latter); this means we have to use +// width-specific functions and type declarations +#define PCRE2_CODE_UNIT_WIDTH 0 +#include "pcre2.h" + #include "platform.h" #include "eclrtl.hpp" #include "eclrtl_imp.hpp" +#include "jlib.hpp" #ifdef _USE_ICU #include "unicode/regex.h" #endif #define UTF8_CODEPAGE "UTF-8" -#define UTF8_MAXSIZE 4 +#define UTF8_MAXSIZE 4 + +//--------------------------------------------------------------------------- + +// PCRE2 8-bit context module variables +static pcre2_general_context_8 * pcre2GeneralContext8; +static pcre2_compile_context_8 * pcre2CompileContext8; +static pcre2_match_context_8 * pcre2MatchContext8; -using boost::regex; -using boost::regex_search; -using boost::regex_replace; -using boost::regex_iterator; -using boost::cmatch; -using boost::match_results; +// PCRE2 memory allocation hook +static void * pcre2Malloc(size_t size, void * /*userData*/) +{ + return rtlMalloc(size); +} + +// PCRE2 memory deallocation hook +static void pcre2Free(void * block, void * /*userData*/) +{ + if (block) + rtlFree(block); +} + +/// @brief Convert a PCRE2 error code to a string and throw an exception +/// @param errCode PCRE2 error code +/// @param msgPrefix Prefix for error message; can be an empty string; +/// include a trailing space if a non-empty message is passed +/// @param regex OPTIONAL; regex pattern that was in play when error occurred +static void failWithPCRE2Error(int errCode, const char * msgPrefix, const char * regex = nullptr) +{ + const int errBuffSize = 120; + char errBuff[errBuffSize]; + std::string msg = msgPrefix; + int msgLen = pcre2_get_error_message_8(errCode, (PCRE2_UCHAR8 *)errBuff, errBuffSize); + if (msgLen > 0) + { + msg += errBuff; + } + else + { + msg += "PCRE2 error code: " ; + msg += std::to_string(errCode); + msg += " (no error message available)"; + } + if (regex && regex[0]) + { + msg += " (regex: "; + msg += regex; + msg += ")"; + } + rtlFail(0, msg.c_str()); +} + +//--------------------------------------------------------------------------- class CStrRegExprFindInstance : implements IStrRegExprFindInstance { private: - bool matched; - const regex * regEx; - cmatch subs; - char * sample; //only required if findstr/findvstr will be called + bool matched = false; + pcre2_code_8 * compiledRegex = nullptr; // do not free; this will be owned by caller + pcre2_match_data_8 * matchData = nullptr; + const char * subject = nullptr; // points to current subject of regex; do not free + char * sample = nullptr; //only required if findstr/findvstr will be called public: - CStrRegExprFindInstance(const regex * _regEx, const char * _str, size32_t _from, size32_t _len, bool _keep) - : regEx(_regEx) + CStrRegExprFindInstance(pcre2_code_8 * _compiledRegex, const char * _subject, size32_t _from, size32_t _len, bool _keep) + : compiledRegex(_compiledRegex) { matched = false; - sample = NULL; - try + sample = nullptr; + matchData = pcre2_match_data_create_from_pattern_8(compiledRegex, pcre2GeneralContext8); + + if (_keep) { - if (_keep) - { - sample = (char *)rtlMalloc(_len + 1); //required for findstr - memcpy(sample, _str + _from, _len); - sample[_len] = '\0'; - matched = regex_search(sample, subs, *regEx); - } - else - { - matched = regex_search(_str + _from, _str + _len, subs, *regEx); - } + sample = (char *)rtlMalloc(_len + 1); //required for findstr + memcpy(sample, _subject + _from, _len); + sample[_len] = '\0'; + subject = sample; } - catch (const std::runtime_error & e) + else { - std::string msg = "Error in regex search: "; - msg += e.what(); - msg += "(regex: "; - msg += regEx->str(); - msg += ")"; - rtlFail(0, msg.c_str()); + subject = _subject + _from; + } + + int numMatches = pcre2_match_8(compiledRegex, (PCRE2_SPTR8)subject, _len, 0, 0, matchData, pcre2MatchContext8); + + matched = numMatches > 0; + + if (numMatches < 0 && numMatches != PCRE2_ERROR_NOMATCH) + { + // Treat everything else as an error + failWithPCRE2Error(numMatches, "Error in regex search: "); } } ~CStrRegExprFindInstance() //CAVEAT non-virtual destructor ! { - free(sample); + if (sample) + rtlFree(sample); + pcre2_match_data_free_8(matchData); } //IStrRegExprFindInstance @@ -85,28 +142,32 @@ class CStrRegExprFindInstance : implements IStrRegExprFindInstance void getMatchX(unsigned & outlen, char * & out, unsigned n = 0) const { - if (matched && (n < subs.size())) + if (matched && (n < pcre2_get_ovector_count_8(matchData))) { - outlen = subs[n].second - subs[n].first; + PCRE2_SIZE * ovector = pcre2_get_ovector_pointer_8(matchData); + const char * matchStart = subject + ovector[2 * n]; + outlen = ovector[2 * n + 1] - ovector[2 * n]; out = (char *)rtlMalloc(outlen); - memcpy_iflen(out, subs[n].first, outlen); + memcpy(out, matchStart, outlen); } else { outlen = 0; - out = NULL; + out = nullptr; } } char const * findvstr(unsigned outlen, char * out, unsigned n = 0) { - if (matched && (n < subs.size())) + if (matched && (n < pcre2_get_ovector_count_8(matchData))) { - unsigned sublen = subs[n].second - subs[n].first; - if (sublen >= outlen) - sublen = outlen - 1; - memcpy(out, subs[n].first, sublen); - out[sublen] = 0; + PCRE2_SIZE * ovector = pcre2_get_ovector_pointer_8(matchData); + const char * matchStart = subject + ovector[2 * n]; + unsigned substrLen = ovector[2 * n + 1] - ovector[2 * n]; + if (substrLen >= outlen) + substrLen = outlen - 1; + memcpy(out, matchStart, substrLen); + out[substrLen] = 0; } else { @@ -121,82 +182,131 @@ class CStrRegExprFindInstance : implements IStrRegExprFindInstance class CCompiledStrRegExpr : implements ICompiledStrRegExpr { private: - regex regEx; + pcre2_code_8 * compiledRegex = nullptr; public: - CCompiledStrRegExpr(const char * _regExp, bool _isCaseSensitive = false) + CCompiledStrRegExpr(const char * _regex, bool _isCaseSensitive = false) { - try - { - if (_isCaseSensitive) - regEx.assign(_regExp, regex::perl); - else - regEx.assign(_regExp, regex::perl | regex::icase); - } - catch(const boost::bad_expression & e) + int errNum = 0; + PCRE2_SIZE errOffset; + uint32_t options = (_isCaseSensitive ? 0 : PCRE2_CASELESS); + + compiledRegex = pcre2_compile_8((PCRE2_SPTR8)_regex, PCRE2_ZERO_TERMINATED, options, &errNum, &errOffset, pcre2CompileContext8); + + if (compiledRegex == nullptr) { - std::string msg = "Bad regular expression: "; - msg += e.what(); - msg += ": "; - msg += _regExp; - rtlFail(0, msg.c_str()); //throws + failWithPCRE2Error(errNum, "Error in regex pattern: ", _regex); } } + ~CCompiledStrRegExpr() //CAVEAT non-virtual destructor ! + { + pcre2_code_free_8(compiledRegex); + } + //ICompiledStrRegExpr void replace(size32_t & outlen, char * & out, size32_t slen, char const * str, size32_t rlen, char const * replace) const { - std::string src(str, str + slen); - std::string fmt(replace, replace + rlen); - std::string tgt; - try + PCRE2_SIZE pcreLen = 0; + outlen = 0; + pcre2_match_data_8 * matchData = pcre2_match_data_create_from_pattern_8(compiledRegex, pcre2GeneralContext8); + + // Call it once to get the size of the output, then allocate memory for it; + // Note that pcreLen will include space for a terminating null character; + // we have to allocate memory for that byte to avoid a buffer overrun, + // but we won't count that terminating byte + int replaceResult = pcre2_substitute_8(compiledRegex, (PCRE2_SPTR8)str, slen, 0, PCRE2_SUBSTITUTE_GLOBAL|PCRE2_SUBSTITUTE_OVERFLOW_LENGTH, matchData, pcre2MatchContext8, (PCRE2_SPTR8)replace, rlen, nullptr, &pcreLen); + + if (replaceResult < 0 && replaceResult != PCRE2_ERROR_NOMEMORY) { -// tgt = boost::regex_merge(src, cre->regEx, fmt, boost::format_perl); //Algorithm regex_merge has been renamed regex_replace, existing code will continue to compile, but new code should use regex_replace instead. - tgt = regex_replace(src, regEx, fmt, boost::format_perl); + // PCRE2_ERROR_NOMEMORY is a normal result when we're just asking for the size of the output + pcre2_match_data_free_8(matchData); + failWithPCRE2Error(replaceResult, "Error in regex replace: "); } - catch(const std::runtime_error & e) + + if (pcreLen > 0) { - std::string msg = "Error in regex replace: "; - msg += e.what(); - msg += "(regex: "; - msg += regEx.str(); - msg += ")"; - rtlFail(0, msg.c_str()); + out = (char *)rtlMalloc(pcreLen); + + replaceResult = pcre2_substitute_8(compiledRegex, (PCRE2_SPTR8)str, slen, 0, PCRE2_SUBSTITUTE_GLOBAL, matchData, pcre2MatchContext8, (PCRE2_SPTR8)replace, rlen, (PCRE2_UCHAR8 *)out, &pcreLen); + + // Note that, weirdly, pcreLen will now contain the number of bytes + // in the result *excluding* the null terminator, so pcreLen will + // become our final result length + + if (replaceResult < 0) + { + pcre2_match_data_free_8(matchData); + failWithPCRE2Error(replaceResult, "Error in regex replace: "); + } } - outlen = tgt.length(); - out = (char *)rtlMalloc(outlen); - memcpy_iflen(out, tgt.data(), outlen); + + pcre2_match_data_free_8(matchData); + outlen = pcreLen; } IStrRegExprFindInstance * find(const char * str, size32_t from, size32_t len, bool needToKeepSearchString) const { - CStrRegExprFindInstance * findInst = new CStrRegExprFindInstance(®Ex, str, from, len, needToKeepSearchString); + CStrRegExprFindInstance * findInst = new CStrRegExprFindInstance(compiledRegex, str, from, len, needToKeepSearchString); return findInst; } - void getMatchSet(bool & __isAllResult, size32_t & __resultBytes, void * & __result, size32_t _srcLen, const char * _search) + void getMatchSet(bool & __isAllResult, size32_t & __resultBytes, void * & __result, size32_t _subjectLen, const char * _subject) { rtlRowBuilder out; size32_t outBytes = 0; - const char * search_end = _search+_srcLen; + PCRE2_SIZE offset = 0; + pcre2_match_data_8 * matchData = pcre2_match_data_create_from_pattern_8(compiledRegex, pcre2GeneralContext8); + + // Capture groups are ignored when gathering match results into a set, + // so we will focus on only the first match (the entire matched string); + // then we need to repeatedly match, adjusting the offset into the + // subject string each time, until no more matches are found - regex_iterator cur(_search, search_end, regEx); - regex_iterator end; // Default contructor creates an end of list marker - for (; cur != end; ++cur) + while (offset < _subjectLen) { - const match_results &match = *cur; - if (match[0].first==search_end) break; + int numMatches = pcre2_match_8(compiledRegex, (PCRE2_SPTR8)_subject, _subjectLen, offset, 0, matchData, pcre2MatchContext8); - const size32_t lenBytes = match[0].second - match[0].first; - out.ensureAvailable(outBytes+lenBytes+sizeof(size32_t)); - byte *outData = out.getbytes()+outBytes; + if (numMatches < 0) + { + if (numMatches == PCRE2_ERROR_NOMATCH) + { + // No more matches; bail out of loop + break; + } + else + { + // Treat everything else as an error + pcre2_match_data_free_8(matchData); + failWithPCRE2Error(numMatches, "Error in regex getMatchSet: "); + } + } + else if (numMatches > 0) + { + PCRE2_SIZE * ovector = pcre2_get_ovector_pointer_8(matchData); + const char * matchStart = _subject + ovector[0]; + unsigned matchLen = ovector[1] - ovector[0]; + + // Copy match to output buffer + out.ensureAvailable(outBytes + matchLen + sizeof(size32_t)); + byte * outData = out.getbytes() + outBytes; + * (size32_t *) outData = matchLen; + memcpy(outData + sizeof(size32_t), matchStart, matchLen); + outBytes += matchLen + sizeof(size32_t); + + // Update offset + offset += matchLen + 1; + } + else + { + // This should never happen + break; + } + } - * (size32_t *) outData = lenBytes; - rtlStrToStr(lenBytes, outData+sizeof(size32_t), lenBytes, match[0].first); + pcre2_match_data_free_8(matchData); - outBytes += lenBytes+sizeof(size32_t); - } __isAllResult = false; __resultBytes = outBytes; __result = out.detachdata(); @@ -277,7 +387,7 @@ class CUStrRegExprFindInstance : implements IUStrRegExprFindInstance else { outlen = 0; - out = NULL; + out = nullptr; } } @@ -435,3 +545,18 @@ ECLRTL_API void rtlDestroyUStrRegExprFindInstance(IUStrRegExprFindInstance * fin { } #endif + +MODULE_INIT(INIT_PRIORITY_ECLRTL_ECLRTL) +{ + pcre2GeneralContext8 = pcre2_general_context_create_8(pcre2Malloc, pcre2Free, NULL); + pcre2CompileContext8 = pcre2_compile_context_create_8(pcre2GeneralContext8); + pcre2MatchContext8 = pcre2_match_context_create_8(pcre2GeneralContext8); + return true; +} + +MODULE_EXIT() +{ + pcre2_match_context_free_8(pcre2MatchContext8); + pcre2_compile_context_free_8(pcre2CompileContext8); + pcre2_general_context_free_8(pcre2GeneralContext8); +} diff --git a/rtl/eclrtl/eclrtl.hpp b/rtl/eclrtl/eclrtl.hpp index 36c45e94e59..8e43c30567d 100644 --- a/rtl/eclrtl/eclrtl.hpp +++ b/rtl/eclrtl/eclrtl.hpp @@ -77,7 +77,7 @@ enum DBZaction { DBZnone, DBZzero, DBZnan, DBZfail }; // Different actions on di //----------------------------------------------------------------------------- -// RegEx Compiler for ansii strings (uses BOOST or std::regex) +// RegEx Compiler for ansii strings (uses PCRE2) interface IStrRegExprFindInstance { virtual bool found() const = 0; diff --git a/testing/regress/ecl/key/regex_string_1.xml b/testing/regress/ecl/key/regex_string_1.xml new file mode 100644 index 00000000000..cf32b1ed0db --- /dev/null +++ b/testing/regress/ecl/key/regex_string_1.xml @@ -0,0 +1,9 @@ + + 922 + + + 827 + + + 95 + diff --git a/testing/regress/ecl/regex_string_1.ecl b/testing/regress/ecl/regex_string_1.ecl new file mode 100644 index 00000000000..dbefa364457 --- /dev/null +++ b/testing/regress/ecl/regex_string_1.ecl @@ -0,0 +1,964 @@ +/*############################################################################## + + HPCC SYSTEMS software Copyright (C) 2024 HPCC Systems®. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +############################################################################## */ + +//Tests derived from the python3 test suite + +#OPTION('globalFold', FALSE); + +regexTests := DATASET + ( + [ + {'abc', 'abc', TRUE}, + {'abc', 'xbc', FALSE}, + {'abc', 'axc', FALSE}, + {'abc', 'abx', FALSE}, + {'abc', 'xabcy', TRUE}, + {'abc', 'ababc', TRUE}, + {'ab*c', 'abc', TRUE}, + {'ab*bc', 'abc', TRUE}, + {'ab*bc', 'abbc', TRUE}, + {'ab*bc', 'abbbbc', TRUE}, + {'.{1}', 'abbbbc', TRUE}, + {'.{3,4}', 'abbbbc', TRUE}, + {'ab{0,}bc', 'abbbbc', TRUE}, + {'ab+bc', 'abbc', TRUE}, + {'ab+bc', 'abc', FALSE}, + {'ab+bc', 'abq', FALSE}, + {'ab{1,}bc', 'abq', FALSE}, + {'ab+bc', 'abbbbc', TRUE}, + {'ab{1,}bc', 'abbbbc', TRUE}, + {'ab{1,3}bc', 'abbbbc', TRUE}, + {'ab{3,4}bc', 'abbbbc', TRUE}, + {'ab{4,5}bc', 'abbbbc', FALSE}, + {'ab?bc', 'abbc', TRUE}, + {'ab?bc', 'abc', TRUE}, + {'ab{0,1}bc', 'abc', TRUE}, + {'ab?bc', 'abbbbc', FALSE}, + {'ab?c', 'abc', TRUE}, + {'ab{0,1}c', 'abc', TRUE}, + {'^abc$', 'abc', TRUE}, + {'^abc$', 'abcc', FALSE}, + {'^abc', 'abcc', TRUE}, + {'^abc$', 'aabc', FALSE}, + {'abc$', 'aabc', TRUE}, + {'abc$', 'aabcd', FALSE}, + {'^', 'abc', TRUE}, + {'$', 'abc', TRUE}, + {'a.c', 'abc', TRUE}, + {'a.c', 'axc', TRUE}, + {'a\nc', 'abc', TRUE}, + {'a.*c', 'axyzc', TRUE}, + {'a\n*c', 'axyzc', TRUE}, + {'a.*c', 'axyzd', FALSE}, + {'a\n*c', 'axyzd', FALSE}, + {'a[bc]d', 'abc', FALSE}, + {'a[bc]d', 'abd', TRUE}, + {'a[b]d', 'abd', TRUE}, + {'[a][b][d]', 'abd', TRUE}, + {'.[b].', 'abd', TRUE}, + {'.[b].', 'aBd', FALSE}, + {'(?i:.[b].)', 'abd', TRUE}, + {'(?i:\n[b]\n)', 'abd', TRUE}, + {'a[b-d]e', 'abd', FALSE}, + {'a[b-d]e', 'ace', TRUE}, + {'a[b-d]', 'aac', TRUE}, + {'a[-b]', 'a-', TRUE}, + {'a[b-]', 'a-', TRUE}, + {'a]', 'a]', TRUE}, + {'a[]]b', 'a]b', TRUE}, + {'a[^bc]d', 'aed', TRUE}, + {'a[^bc]d', 'abd', FALSE}, + {'a[^-b]c', 'adc', TRUE}, + {'a[^-b]c', 'a-c', FALSE}, + {'a[^]b]c', 'a]c', FALSE}, + {'a[^]b]c', 'adc', TRUE}, + {'\\ba\\b', 'a-', TRUE}, + {'\\ba\\b', '-a', TRUE}, + {'\\ba\\b', '-a-', TRUE}, + {'\\by\\b', 'xy', FALSE}, + {'\\by\\b', 'yz', FALSE}, + {'\\by\\b', 'xyz', FALSE}, + {'\\Ba\\B', 'a-', FALSE}, + {'\\Ba\\B', '-a', FALSE}, + {'\\Ba\\B', '-a-', FALSE}, + {'\\By\\b', 'xy', TRUE}, + {'\\by\\B', 'yz', TRUE}, + {'\\By\\B', 'xyz', TRUE}, + {'\\w', 'a', TRUE}, + {'\\w', '-', FALSE}, + {'\\W', 'a', FALSE}, + {'\\W', '-', TRUE}, + {'a\\sb', 'a b', TRUE}, + {'a\\sb', 'a-b', FALSE}, + {'a\\Sb', 'a b', FALSE}, + {'a\\Sb', 'a-b', TRUE}, + {'\\d', '1', TRUE}, + {'\\d', '-', FALSE}, + {'\\D', '1', FALSE}, + {'\\D', '-', TRUE}, + {'[\\w]', 'a', TRUE}, + {'[\\w]', '-', FALSE}, + {'[\\W]', 'a', FALSE}, + {'[\\W]', '-', TRUE}, + {'a[\\s]b', 'a b', TRUE}, + {'a[\\s]b', 'a-b', FALSE}, + {'a[\\S]b', 'a b', FALSE}, + {'a[\\S]b', 'a-b', TRUE}, + {'[\\d]', '1', TRUE}, + {'[\\d]', '-', FALSE}, + {'[\\D]', '1', FALSE}, + {'[\\D]', '-', TRUE}, + {'ab|cd', 'abc', TRUE}, + {'ab|cd', 'abcd', TRUE}, + {'()ef', 'def', TRUE}, + {'$b', 'b', FALSE}, + {'a\\(b', 'a(b', TRUE}, + {'a\\(*b', 'ab', TRUE}, + {'a\\(*b', 'a((b', TRUE}, + {'a\\\\b', 'a\\\\b', TRUE}, + {'((a))', 'abc', TRUE}, + {'(a)b(c)', 'abc', TRUE}, + {'a+b+c', 'aabbabc', TRUE}, + {'a{1,}b{1,}c', 'aabbabc', TRUE}, + {'a.+?c', 'abcabc', TRUE}, + {'(a+|b)*', 'ab', TRUE}, + {'(a+|b){0,}', 'ab', TRUE}, + {'(a+|b)+', 'ab', TRUE}, + {'(a+|b){1,}', 'ab', TRUE}, + {'(a+|b)?', 'ab', TRUE}, + {'(a+|b){0,1}', 'ab', TRUE}, + {'[^ab]*', 'cde', TRUE}, + {'([abc])*d', 'abbbcd', TRUE}, + {'([abc])*bcd', 'abcd', TRUE}, + {'a|b|c|d|e', 'e', TRUE}, + {'(a|b|c|d|e)f', 'ef', TRUE}, + {'abcd*efg', 'abcdefg', TRUE}, + {'ab*', 'xabyabbbz', TRUE}, + {'ab*', 'xayabbbz', TRUE}, + {'(ab|cd)e', 'abcde', TRUE}, + {'[abhgefdc]ij', 'hij', TRUE}, + {'^(ab|cd)e', 'abcde', FALSE}, + {'(abc|)ef', 'abcdef', TRUE}, + {'(a|b)c*d', 'abcd', TRUE}, + {'(ab|ab*)bc', 'abc', TRUE}, + {'a([bc]*)c*', 'abc', TRUE}, + {'a([bc]*)(c*d)', 'abcd', TRUE}, + {'a([bc]+)(c*d)', 'abcd', TRUE}, + {'a([bc]*)(c+d)', 'abcd', TRUE}, + {'a[bcd]*dcdcde', 'adcdcde', TRUE}, + {'a[bcd]+dcdcde', 'adcdcde', FALSE}, + {'(ab|a)b*c', 'abc', TRUE}, + {'((a)(b)c)(d)', 'abcd', TRUE}, + {'[a-zA-Z_][a-zA-Z0-9_]*', 'alpha', TRUE}, + {'[_A-Z]', '}', FALSE}, + {'^a(bc+|b[eh])g|.h$', 'abh', TRUE}, + {'(bc+d$|ef*g.|h?i(j|k))', 'effgz', TRUE}, + {'(bc+d$|ef*g.|h?i(j|k))', 'ij', TRUE}, + {'(bc+d$|ef*g.|h?i(j|k))', 'effg', FALSE}, + {'(bc+d$|ef*g.|h?i(j|k))', 'bcdd', FALSE}, + {'(bc+d$|ef*g.|h?i(j|k))', 'reffgz', TRUE}, + {'((((((((((a))))))))))', 'a', TRUE}, + {'((((((((((a))))))))))\\10', 'aa', TRUE}, + {'((((((((((a))))))))))${bang}', 'aa', FALSE}, + {'((((((((((a))))))))))${bang}', 'a!', TRUE}, + {'(((((((((a)))))))))', 'a', TRUE}, + {'[89]+', '1((((((7(9))))))', TRUE}, + {'multiple words of text', 'uh-uh', FALSE}, + {'multiple words', 'multiple words, yeah', TRUE}, + {'(.*)c(.*)', 'abcde', TRUE}, + {'\\((.*), (.*)\\)', '(a, b)', TRUE}, + {'[k]', 'ab', FALSE}, + {'abcd', 'abcd', TRUE}, + {'a(bc)d', 'abcd', TRUE}, + {'a[-]?c', 'ac', TRUE}, + {'(abc)\\1', 'abcabc', TRUE}, + {'([a-c]*)\\1', 'abcabc', TRUE}, + {'(a)|\\1', 'a', TRUE}, + {'(a)|\\1', 'x', FALSE}, + {'(?:(b)?a)\\1', 'a', FALSE}, + {'(([a-c])b*?\\2)*', 'ababbbcbc', TRUE}, + {'(([a-c])b*?\\2){3}', 'ababbbcbc', TRUE}, + {'((\\3|b)\\2(a)x)+', 'aaxabxbaxbbx', FALSE}, + {'((\\3|b)\\2(a)x)+', 'aaaxabaxbaaxbbax', TRUE}, + {'((\\3|b)\\2(a)){2,}', 'bbaababbabaaaaabbaaaabba', TRUE}, + {'^((.)?a\\2)+$', 'babadad', FALSE}, + {'(a)|(b)', 'b', TRUE}, + {'a(?!b).', 'abad', TRUE}, + {'a(?=d).', 'abad', TRUE}, + {'a(?=c|d).', 'abad', TRUE}, + {'a(?:b|c|d)(.)', 'ace', TRUE}, + {'a(?:b|c|d)*(.)', 'ace', TRUE}, + {'a(?:b|c|d)+?(.)', 'ace', TRUE}, + {'a(?:b|c|d)+?(.)', 'acdbcdbe', TRUE}, + {'a(?:b|c|d)+(.)', 'acdbcdbe', TRUE}, + {'a(?:b|c|d){2}(.)', 'acdbcdbe', TRUE}, + {'a(?:b|c|d){4,5}(.)', 'acdbcdbe', TRUE}, + {'a(?:b|c|d){4,5}?(.)', 'acdbcdbe', TRUE}, + {'((foo)|(bar))*', 'foobar', TRUE}, + {'a(?:b|c|d){6,7}(.)', 'acdbcdbe', TRUE}, + {'a(?:b|c|d){6,7}?(.)', 'acdbcdbe', TRUE}, + {'a(?:b|c|d){5,6}(.)', 'acdbcdbe', TRUE}, + {'a(?:b|c|d){5,6}?(.)', 'acdbcdbe', TRUE}, + {'a(?:b|c|d){5,7}(.)', 'acdbcdbe', TRUE}, + {'a(?:b|c|d){5,7}?(.)', 'acdbcdbe', TRUE}, + {'a(?:b|(c|e){1,2}?|d)+?(.)', 'ace', TRUE}, + {'^(.+)?B', 'AB', TRUE}, + {'^([^a-z])|(\\^)$', '.', TRUE}, + {'^[<>]&', '<&OUT', TRUE}, + {'^(a\\1?){4}$', 'aaaaaaaaaa', TRUE}, + {'^(a\\1?){4}$', 'aaaaaaaaa', FALSE}, + {'^(a\\1?){4}$', 'aaaaaaaaaaa', FALSE}, + {'^(a(?(1)\\1)){4}$', 'aaaaaaaaaa', TRUE}, + {'^(a(?(1)\\1)){4}$', 'aaaaaaaaa', FALSE}, + {'^(a(?(1)\\1)){4}$', 'aaaaaaaaaaa', FALSE}, + {'((?(1)a|b))+', 'baaa', TRUE}, + {'((?(1)aa|b))+', 'baaaa', TRUE}, + {'((a{4})+)', 'aaaaaaaaa', TRUE}, + {'(((aa){2})+)', 'aaaaaaaaaa', TRUE}, + {'(((a{2}){2})+)', 'aaaaaaaaaa', TRUE}, + {'(?:(f)(o)(o)|(b)(a)(r))*', 'foobar', TRUE}, + {'(?<=a)b', 'ab', TRUE}, + {'(?<=a)b', 'cb', FALSE}, + {'(?<=a)b', 'b', FALSE}, + {'(?a+)ab', 'aaab', FALSE}, + {'(?>a+)b', 'aaab', TRUE}, + {'([[:alpha:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:alnum:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:cntrl:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:digit:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:graph:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:lower:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:print:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:punct:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:space:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:word:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:upper:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:xdigit:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:^alpha:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:^cntrl:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:^digit:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:^lower:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:^punct:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:^space:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:^upper:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'([[:^xdigit:]]+)', 'ABcd01Xy__-- ${nulnul}${ffff}', TRUE}, + {'\'[[:^cntrl:]]+\'u', 'a\\x80', TRUE}, + {'((?>a+)b)', 'aaab', TRUE}, + {'(?>(a+))b', 'aaab', TRUE}, + {'((?>[^()]+)|\\([^()]*\\))+', '((abc(ade)ufh()()x', TRUE}, + {'\\z', 'a\nb\n', TRUE}, + {'$', 'a\nb\n', TRUE}, + {'\\z', 'b\na\n', TRUE}, + {'$', 'b\na\n', TRUE}, + {'\\z', 'b\na', TRUE}, + {'$', 'b\na', TRUE}, + {'\'\\z\'m', 'a\nb\n', TRUE}, + {'\'$\'m', 'a\nb\n', TRUE}, + {'\'\\z\'m', 'b\na\n', TRUE}, + {'\'$\'m', 'b\na\n', TRUE}, + {'\'\\z\'m', 'b\na', TRUE}, + {'\'$\'m', 'b\na', TRUE}, + {'a\\z', 'a\nb\n', FALSE}, + {'a$', 'a\nb\n', FALSE}, + {'a\\Z', 'b\na\n', TRUE}, + {'a\\z', 'b\na\n', FALSE}, + {'a$', 'b\na\n', TRUE}, + {'a\\z', 'b\na', TRUE}, + {'a$', 'b\na', TRUE}, + {'\'a\\z\'m', 'a\nb\n', FALSE}, + {'\'a$\'m', 'a\nb\n', TRUE}, + {'\'a\\Z\'m', 'b\na\n', TRUE}, + {'\'a\\z\'m', 'b\na\n', FALSE}, + {'\'a$\'m', 'b\na\n', TRUE}, + {'\'a\\z\'m', 'b\na', TRUE}, + {'\'a$\'m', 'b\na', TRUE}, + {'aa\\z', 'aa\nb\n', FALSE}, + {'aa$', 'aa\nb\n', FALSE}, + {'aa\\Z', 'b\naa\n', TRUE}, + {'aa\\z', 'b\naa\n', FALSE}, + {'aa$', 'b\naa\n', TRUE}, + {'aa\\z', 'b\naa', TRUE}, + {'aa$', 'b\naa', TRUE}, + {'\'aa\\z\'m', 'aa\nb\n', FALSE}, + {'\'aa$\'m', 'aa\nb\n', TRUE}, + {'\'aa\\Z\'m', 'b\naa\n', TRUE}, + {'\'aa\\z\'m', 'b\naa\n', FALSE}, + {'\'aa$\'m', 'b\naa\n', TRUE}, + {'\'aa\\z\'m', 'b\naa', TRUE}, + {'\'aa$\'m', 'b\naa', TRUE}, + {'aa\\z', 'ac\nb\n', FALSE}, + {'aa$', 'ac\nb\n', FALSE}, + {'aa\\z', 'b\nac\n', FALSE}, + {'aa$', 'b\nac\n', FALSE}, + {'aa\\z', 'b\nac', FALSE}, + {'aa$', 'b\nac', FALSE}, + {'\'aa\\z\'m', 'ac\nb\n', FALSE}, + {'\'aa$\'m', 'ac\nb\n', FALSE}, + {'\'aa\\z\'m', 'b\nac\n', FALSE}, + {'\'aa$\'m', 'b\nac\n', FALSE}, + {'\'aa\\z\'m', 'b\nac', FALSE}, + {'\'aa$\'m', 'b\nac', FALSE}, + {'aa\\z', 'ca\nb\n', FALSE}, + {'aa$', 'ca\nb\n', FALSE}, + {'aa\\z', 'b\nca\n', FALSE}, + {'aa$', 'b\nca\n', FALSE}, + {'aa\\z', 'b\nca', FALSE}, + {'aa$', 'b\nca', FALSE}, + {'\'aa\\z\'m', 'ca\nb\n', FALSE}, + {'\'aa$\'m', 'ca\nb\n', FALSE}, + {'\'aa\\z\'m', 'b\nca\n', FALSE}, + {'\'aa$\'m', 'b\nca\n', FALSE}, + {'\'aa\\z\'m', 'b\nca', FALSE}, + {'\'aa$\'m', 'b\nca', FALSE}, + {'ab\\z', 'ab\nb\n', FALSE}, + {'ab$', 'ab\nb\n', FALSE}, + {'ab\\Z', 'b\nab\n', TRUE}, + {'ab\\z', 'b\nab\n', FALSE}, + {'ab$', 'b\nab\n', TRUE}, + {'ab\\z', 'b\nab', TRUE}, + {'ab$', 'b\nab', TRUE}, + {'\'ab\\z\'m', 'ab\nb\n', FALSE}, + {'\'ab$\'m', 'ab\nb\n', TRUE}, + {'\'ab\\Z\'m', 'b\nab\n', TRUE}, + {'\'ab\\z\'m', 'b\nab\n', FALSE}, + {'\'ab$\'m', 'b\nab\n', TRUE}, + {'\'ab\\z\'m', 'b\nab', TRUE}, + {'\'ab$\'m', 'b\nab', TRUE}, + {'ab\\z', 'ac\nb\n', FALSE}, + {'ab$', 'ac\nb\n', FALSE}, + {'ab\\z', 'b\nac\n', FALSE}, + {'ab$', 'b\nac\n', FALSE}, + {'ab\\z', 'b\nac', FALSE}, + {'ab$', 'b\nac', FALSE}, + {'\'ab\\z\'m', 'ac\nb\n', FALSE}, + {'\'ab$\'m', 'ac\nb\n', FALSE}, + {'\'ab\\z\'m', 'b\nac\n', FALSE}, + {'\'ab$\'m', 'b\nac\n', FALSE}, + {'\'ab\\z\'m', 'b\nac', FALSE}, + {'\'ab$\'m', 'b\nac', FALSE}, + {'ab\\z', 'ca\nb\n', FALSE}, + {'ab$', 'ca\nb\n', FALSE}, + {'ab\\z', 'b\nca\n', FALSE}, + {'ab$', 'b\nca\n', FALSE}, + {'ab\\z', 'b\nca', FALSE}, + {'ab$', 'b\nca', FALSE}, + {'\'ab\\z\'m', 'ca\nb\n', FALSE}, + {'\'ab$\'m', 'ca\nb\n', FALSE}, + {'\'ab\\z\'m', 'b\nca\n', FALSE}, + {'\'ab$\'m', 'b\nca\n', FALSE}, + {'\'ab\\z\'m', 'b\nca', FALSE}, + {'\'ab$\'m', 'b\nca', FALSE}, + {'abb\\z', 'abb\nb\n', FALSE}, + {'abb$', 'abb\nb\n', FALSE}, + {'abb\\Z', 'b\nabb\n', TRUE}, + {'abb\\z', 'b\nabb\n', FALSE}, + {'abb$', 'b\nabb\n', TRUE}, + {'abb\\z', 'b\nabb', TRUE}, + {'abb$', 'b\nabb', TRUE}, + {'\'abb\\z\'m', 'abb\nb\n', FALSE}, + {'\'abb$\'m', 'abb\nb\n', TRUE}, + {'\'abb\\Z\'m', 'b\nabb\n', TRUE}, + {'\'abb\\z\'m', 'b\nabb\n', FALSE}, + {'\'abb$\'m', 'b\nabb\n', TRUE}, + {'\'abb\\z\'m', 'b\nabb', TRUE}, + {'\'abb$\'m', 'b\nabb', TRUE}, + {'abb\\z', 'ac\nb\n', FALSE}, + {'abb$', 'ac\nb\n', FALSE}, + {'abb\\z', 'b\nac\n', FALSE}, + {'abb$', 'b\nac\n', FALSE}, + {'abb\\z', 'b\nac', FALSE}, + {'abb$', 'b\nac', FALSE}, + {'\'abb\\z\'m', 'ac\nb\n', FALSE}, + {'\'abb$\'m', 'ac\nb\n', FALSE}, + {'\'abb\\z\'m', 'b\nac\n', FALSE}, + {'\'abb$\'m', 'b\nac\n', FALSE}, + {'\'abb\\z\'m', 'b\nac', FALSE}, + {'\'abb$\'m', 'b\nac', FALSE}, + {'abb\\z', 'ca\nb\n', FALSE}, + {'abb$', 'ca\nb\n', FALSE}, + {'abb\\z', 'b\nca\n', FALSE}, + {'abb$', 'b\nca\n', FALSE}, + {'abb\\z', 'b\nca', FALSE}, + {'abb$', 'b\nca', FALSE}, + {'\'abb\\z\'m', 'ca\nb\n', FALSE}, + {'\'abb$\'m', 'ca\nb\n', FALSE}, + {'\'abb\\z\'m', 'b\nca\n', FALSE}, + {'\'abb$\'m', 'b\nca\n', FALSE}, + {'\'abb\\z\'m', 'b\nca', FALSE}, + {'\'abb$\'m', 'b\nca', FALSE}, + {'\'\\Aa$\'m', 'a\n\n', TRUE}, + {'(^|x)(c)', 'ca', TRUE}, + {'a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz', 'x', FALSE}, + {'round\\(((?>[^()]+))\\)', '_I(round(xs * sz),1)', TRUE}, + {'\'((?x:.) )\'', 'x ', TRUE}, + {'\'((?-x:.) )\'x', 'x ', TRUE}, + {'foo.bart', 'foo.bart', TRUE}, + {'\'^d[x][x][x]\'m', 'abcd\ndxxx', TRUE}, + {'tt+$', 'xxxtt', TRUE}, + {'\\GX.*X', 'aaaXbX', FALSE}, + {'(\\d+\\.\\d+)', '3.1415926', TRUE}, + {'(\\ba.{0,10}br)', 'have a web browser', TRUE}, + {'^([a-z]:)', 'C:/', FALSE}, + {'\'^\\S\\s+aa$\'m', '\nx aa', TRUE}, + {'(^|a)b', 'ab', TRUE}, + {'^([ab]*?)(b)?(c)$', 'abac', TRUE}, + {'(\\w)?(abc)\\1b', 'abcab', FALSE}, + {'^(?:.,){2}c', 'a,b,c', TRUE}, + {'^(.,){2}c', 'a,b,c', TRUE}, + {'^(?:[^,]*,){2}c', 'a,b,c', TRUE}, + {'^([^,]*,){2}c', 'a,b,c', TRUE}, + {'^([^,]*,){3}d', 'aaa,b,c,d', TRUE}, + {'^([^,]*,){3,}d', 'aaa,b,c,d', TRUE}, + {'^([^,]*,){0,3}d', 'aaa,b,c,d', TRUE}, + {'^([^,]{1,3},){3}d', 'aaa,b,c,d', TRUE}, + {'^([^,]{1,3},){3,}d', 'aaa,b,c,d', TRUE}, + {'^([^,]{1,3},){0,3}d', 'aaa,b,c,d', TRUE}, + {'^([^,]{1,},){3}d', 'aaa,b,c,d', TRUE}, + {'^([^,]{1,},){3,}d', 'aaa,b,c,d', TRUE}, + {'^([^,]{1,},){0,3}d', 'aaa,b,c,d', TRUE}, + {'^([^,]{0,3},){3}d', 'aaa,b,c,d', TRUE}, + {'^([^,]{0,3},){3,}d', 'aaa,b,c,d', TRUE}, + {'^([^,]{0,3},){0,3}d', 'aaa,b,c,d', TRUE}, + {'\'(?!\\A)x\'m', 'a\nxb\n', TRUE}, + {'^(a(b)?)+$', 'aba', TRUE}, + {'^(aa(bb)?)+$', 'aabbaa', TRUE}, + {'\'^.{9}abc.*\n\'m', '123\nabcabcabcabc\n', TRUE}, + {'^(a)?a$', 'a', TRUE}, + {'^(a)?(?(1)a|b)+$', 'a', FALSE}, + {'^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$', 'aaaaaa', TRUE}, + {'^(a\\1?){4}$', 'aaaaaa', TRUE}, + {'^(0+)?(?:x(1))?', 'x1', TRUE}, + {'^([0-9a-fA-F]+)(?:x([0-9a-fA-F]+)?)(?:x([0-9a-fA-F]+))?', '012cxx0190', TRUE}, + {'^(b+?|a){1,2}c', 'bbbac', TRUE}, + {'^(b+?|a){1,2}c', 'bbbbac', TRUE}, + {'\\((\\w\\. \\w+)\\)', 'cd. (A. Tw)', TRUE}, + {'((?:aaaa|bbbb)cccc)?', 'aaaacccc', TRUE}, + {'((?:aaaa|bbbb)cccc)?', 'bbbbcccc', TRUE}, + {'(a)?(a)+', 'a', TRUE}, + {'(ab)?(ab)+', 'ab', TRUE}, + {'(abc)?(abc)+', 'abc', TRUE}, + {'\'b\\s^\'m', 'a\nb\n', FALSE}, + {'\\ba', 'a', TRUE}, + {'ab(?i)cd', 'AbCd', FALSE}, + {'ab(?i)cd', 'abCd', TRUE}, + {'(A|B)*(?(1)(CD)|(CD))', 'CD', TRUE}, + {'(A|B)*(?(1)(CD)|(CD))', 'ABCD', TRUE}, + {'(A|B)*?(?(1)(CD)|(CD))', 'CD', TRUE}, + {'(A|B)*?(?(1)(CD)|(CD))', 'ABCD', TRUE}, + {'(.*)\\d+\\1', 'abc12bc', TRUE}, + {'(?m:(foo\\s*$))', 'foo\n bar', TRUE}, + {'(.*)c', 'abcd', TRUE}, + {'(.*)(?=c)', 'abcd', TRUE}, + {'(.*)(?=c)c', 'abcd', TRUE}, + {'(.*)(?=b|c)', 'abcd', TRUE}, + {'(.*)(?=b|c)c', 'abcd', TRUE}, + {'(.*)(?=c|b)', 'abcd', TRUE}, + {'(.*)(?=c|b)c', 'abcd', TRUE}, + {'(.*)(?=[bc])', 'abcd', TRUE}, + {'(.*)(?=[bc])c', 'abcd', TRUE}, + {'(.*)(?<=b)', 'abcd', TRUE}, + {'(.*)(?<=b)c', 'abcd', TRUE}, + {'(.*)(?<=b|c)', 'abcd', TRUE}, + {'(.*)(?<=b|c)c', 'abcd', TRUE}, + {'(.*)(?<=c|b)', 'abcd', TRUE}, + {'(.*)(?<=c|b)c', 'abcd', TRUE}, + {'(.*)(?<=[bc])', 'abcd', TRUE}, + {'(.*)(?<=[bc])c', 'abcd', TRUE}, + {'(.*?)c', 'abcd', TRUE}, + {'(.*?)(?=c)', 'abcd', TRUE}, + {'(.*?)(?=c)c', 'abcd', TRUE}, + {'(.*?)(?=b|c)', 'abcd', TRUE}, + {'(.*?)(?=b|c)c', 'abcd', TRUE}, + {'(.*?)(?=c|b)', 'abcd', TRUE}, + {'(.*?)(?=c|b)c', 'abcd', TRUE}, + {'(.*?)(?=[bc])', 'abcd', TRUE}, + {'(.*?)(?=[bc])c', 'abcd', TRUE}, + {'(.*?)(?<=b)', 'abcd', TRUE}, + {'(.*?)(?<=b)c', 'abcd', TRUE}, + {'(.*?)(?<=b|c)', 'abcd', TRUE}, + {'(.*?)(?<=b|c)c', 'abcd', TRUE}, + {'(.*?)(?<=c|b)', 'abcd', TRUE}, + {'(.*?)(?<=c|b)c', 'abcd', TRUE}, + {'(.*?)(?<=[bc])', 'abcd', TRUE}, + {'(.*?)(?<=[bc])c', 'abcd', TRUE}, + {'2(]*)?$\\1', '2', TRUE}, + {'a(b)??', 'abc', TRUE}, + {'(\\d{1,3}\\.){3,}', '128.134.142.8', TRUE}, + {'^.{3,4}(.+)\\1\\z', 'foobarbar', TRUE}, + {'^(?:f|o|b){3,4}(.+)\\1\\z', 'foobarbar', TRUE}, + {'^.{3,4}((?:b|a|r)+)\\1\\z', 'foobarbar', TRUE}, + {'^(?:f|o|b){3,4}((?:b|a|r)+)\\1\\z', 'foobarbar', TRUE}, + {'^.{3,4}(.+?)\\1\\z', 'foobarbar', TRUE}, + {'^(?:f|o|b){3,4}(.+?)\\1\\z', 'foobarbar', TRUE}, + {'^.{3,4}((?:b|a|r)+?)\\1\\z', 'foobarbar', TRUE}, + {'^(?:f|o|b){3,4}((?:b|a|r)+?)\\1\\z', 'foobarbar', TRUE}, + {'^.{2,3}?(.+)\\1\\z', 'foobarbar', TRUE}, + {'^(?:f|o|b){2,3}?(.+)\\1\\z', 'foobarbar', TRUE}, + {'^.{2,3}?((?:b|a|r)+)\\1\\z', 'foobarbar', TRUE}, + {'^(?:f|o|b){2,3}?((?:b|a|r)+)\\1\\z', 'foobarbar', TRUE}, + {'^.{2,3}?(.+?)\\1\\z', 'foobarbar', TRUE}, + {'^(?:f|o|b){2,3}?(.+?)\\1\\z', 'foobarbar', TRUE}, + {'^.{2,3}?((?:b|a|r)+?)\\1\\z', 'foobarbar', TRUE}, + {'^(?:f|o|b){2,3}?((?:b|a|r)+?)\\1\\z', 'foobarbar', TRUE}, + {'.*a(?!(b|cd)*e).*f', '......abef', FALSE}, + {'(WORDS|WORD)S', 'WORDS', TRUE}, + {'(X.|WORDS|X.|WORD)S', 'WORDS', TRUE}, + {'(WORDS|WORLD|WORD)S', 'WORDS', TRUE}, + {'(X.|WORDS|WORD|Y.)S', 'WORDS', TRUE}, + {'(foo|fool|x.|money|parted)$', 'fool', TRUE}, + {'(x.|foo|fool|x.|money|parted|y.)$', 'fool', TRUE}, + {'(foo|fool|money|parted)$', 'fool', TRUE}, + {'(foo|fool|x.|money|parted)$', 'fools', FALSE}, + {'(x.|foo|fool|x.|money|parted|y.)$', 'fools', FALSE}, + {'(foo|fool|money|parted)$', 'fools', FALSE}, + {'(a|aa|aaa||aaaa|aaaaa|aaaaaa)(b|c)', 'aaaaaaaaaaaaaaab', TRUE}, + {'^(a*?)(?!(aa|aaaa)*$)', 'aaaaaaaaaaaaaaaaaaaa', TRUE}, + {'^(a*?)(?!(aa|aaaa)*$)(?=a\\z)', 'aaaaaaaa', TRUE}, + {'^(.)\\s+.$(?(1))', 'A B', TRUE}, + {'(?:r?)*?r|(.{2,4})', 'abcde', TRUE}, + {'(?!)+?|(.{2,4})', 'abcde', TRUE}, + {'^(a*?)(?!(a{6}|a{5})*$)', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', TRUE}, + {'^((?>(?:aa)?b)?)', 'aab', TRUE}, + {'^((?:aa)*)(?:X+((?:\\d+|-)(?:X+(.+))?))?$', 'aaaaX5', TRUE}, + {'X(A|B||C|D)Y', 'XXXYYY', TRUE}, + {'(?i:X([A]|[B]|y[Y]y|[D]|)Y)', 'XXXYYYB', TRUE}, + {'^([a]{1})*$', 'aa', TRUE}, + {'a(?!b(?!c))(..)', 'abababc', TRUE}, + {'a(?!b(?=a))(..)', 'abababc', TRUE}, + {'a(?!b(?!c(?!d(?!e))))...(.)', 'abxabcdxabcde', TRUE}, + {'X(?!b+(?!(c+)*(?!(c+)*d))).*X', 'aXbbbbbbbcccccccccccccaaaX', TRUE}, + {'^(XXXXXXXXXX|YYYYYYYYYY|Z.Q*X|Z[TE]Q*P):', 'ZEQQQQQQQQQQQQQQQQQQP:', TRUE}, + {'^(XXXXXXXXXX|YYYYYYYYYY|Z.Q*X|Z[TE]Q*P):', 'ZEQQQX:', TRUE}, + {'^([TUV]+|XXXXXXXXXX|YYYYYYYYYY|Z.Q*X|Z[TE]Q*P):', 'ZEQQQQQQQQQQQQQQQQQQP:', TRUE}, + {'^([TUV]+|XXXXXXXXXX|YYYYYYYYYY|Z.Q*X|Z[TE]Q*P):', 'ZEQQQX:', TRUE}, + {'^([TUV]+|XXXXXXXXXX|YYYYYYYYYY|Z.Q*X|Z[TE]Q*P|[MKJ]):', 'ZEQQQQQQQQQQQQQQQQQQP:', TRUE}, + {'^([TUV]+|XXXXXXXXXX|YYYYYYYYYY|Z.Q*X|Z[TE]Q*P|[MKJ]):', 'ZEQQQX:', TRUE}, + {'^(XXX|YYY|Z.Q*X|Z[TE]Q*P):', 'ZEQQQQQQQQQQQQQQQQQQP:', TRUE}, + {'^(XXX|YYY|Z.Q*X|Z[TE]Q*P):', 'ZEQQQX:', TRUE}, + {'^([TUV]+|XXX|YYY|Z.Q*X|Z[TE]Q*P):', 'ZEQQQQQQQQQQQQQQQQQQP:', TRUE}, + {'^([TUV]+|XXX|YYY|Z.Q*X|Z[TE]Q*P):', 'ZEQQQX:', TRUE}, + {'^([TUV]+|XXX|YYY|Z.Q*X|Z[TE]Q*P|[MKJ]):', 'ZEQQQQQQQQQQQQQQQQQQP:', TRUE}, + {'^([TUV]+|XXX|YYY|Z.Q*X|Z[TE]Q*P|[MKJ]):', 'ZEQQQX:', TRUE}, + {'X(?:ABCF[cC]x*|ABCD|ABCF):(?:DIT|DID|DIM)', 'XABCFCxxxxxxxxxx:DIM', TRUE}, + {'(((ABCD|ABCE|ABCF)))(A|B|C[xy]*):', 'ABCFCxxxxxxxxxx:DIM', TRUE}, + {'(?=foo)', 'foo', TRUE}, + {'(?=foo)', 'XfooY', TRUE}, + {'.*(?=foo)', 'XfooY', TRUE}, + {'(?=.*P)P', 'aP', TRUE}, + {'(?<=foo)', 'foo', TRUE}, + {'(?<=foo)', 'XfooY', TRUE}, + {'.*(?<=foo)', 'foo', TRUE}, + {'.*(?<=foo)', 'XfooY', TRUE}, + {'(?<=foo)Y', 'XfooY', TRUE}, + {'o(?<=foo)Y', '..XfooY..', TRUE}, + {'X(?=foo)f', '..XfooY..', TRUE}, + {'X(?=foo)', '..XfooY..', TRUE}, + {'X(?<=foo.)[YZ]', '..XfooXY..', TRUE}, + {'(?=XY*foo)', 'Xfoo', TRUE}, + {'^(?=XY*foo)', 'Xfoo', TRUE}, + {'^(<(?:[^<>]+|(?3)|(?1))*>)()(!>!>!>)$', '<!>!>><>>!>!>!>', TRUE}, + {'^(<(?:[^<>]+|(?1))*>)$', '<<><<<><>>>>', TRUE}, + {'((?2)*)([fF]o+)', 'fooFoFoo', TRUE}, + {'(<(?:[^<>]+|(?R))*>)', '<<><<<><>>>>', TRUE}, + {'(?foo|bar|baz)', 'snofooewa', TRUE}, + {'(?foo|bar|baz)(?[ew]+)', 'snofooewa', TRUE}, + {'(?foo)?(?()bar|nada)', 'foobar', TRUE}, + {'(?foo)?(?()bar|nada)', 'foo-barnada', TRUE}, + {'(?foo)?(?(1)bar|nada)', 'foo-barnada', TRUE}, + {'(?foo(?(R)bar))?(?1)', 'foofoobar', TRUE}, + {'(x)(?foo(?(R&A)bar))?(?&A)', 'xfoofoobar', TRUE}, + {'(x)(?foo(?(R2)bar))?(?&A)', 'xfoofoobar', TRUE}, + {'(?1)(?(DEFINE)(blah))', 'blah', TRUE}, + {'foo(?0)?bar', 'phoofoofoobarbarbarr', TRUE}, + {'foo(?R)?bar', 'phoofoofoobarbarbarr', TRUE}, + {'a++a', 'aaaaa', FALSE}, + {'a*+a', 'aaaaa', FALSE}, + {'a{1,5}+a', 'aaaaa', FALSE}, + {'a?+a', 'ab', FALSE}, + {'a++b', 'aaaaab', TRUE}, + {'a*+b', 'aaaaab', TRUE}, + {'a{1,5}+b', 'aaaaab', TRUE}, + {'a?+b', 'ab', TRUE}, + {'fooa++a', 'fooaaaaa', FALSE}, + {'fooa*+a', 'fooaaaaa', FALSE}, + {'fooa{1,5}+a', 'fooaaaaa', FALSE}, + {'fooa?+a', 'fooab', FALSE}, + {'fooa++b', 'fooaaaaab', TRUE}, + {'fooa*+b', 'fooaaaaab', TRUE}, + {'fooa{1,5}+b', 'fooaaaaab', TRUE}, + {'fooa?+b', 'fooab', TRUE}, + {'(?:aA)++(?:aA)', 'aAaAaAaAaA', FALSE}, + {'(aA)++(aA)', 'aAaAaAaAaA', FALSE}, + {'(aA|bB)++(aA|bB)', 'aAaAbBaAbB', FALSE}, + {'(?:aA|bB)++(?:aA|bB)', 'aAbBbBbBaA', FALSE}, + {'(?:aA)*+(?:aA)', 'aAaAaAaAaA', FALSE}, + {'(aA)*+(aA)', 'aAaAaAaAaA', FALSE}, + {'(aA|bB)*+(aA|bB)', 'aAaAbBaAaA', FALSE}, + {'(?:aA|bB)*+(?:aA|bB)', 'aAaAaAbBaA', FALSE}, + {'(?:aA){1,5}+(?:aA)', 'aAaAaAaAaA', FALSE}, + {'(aA){1,5}+(aA)', 'aAaAaAaAaA', FALSE}, + {'(aA|bB){1,5}+(aA|bB)', 'aAaAbBaAaA', FALSE}, + {'(?:aA|bB){1,5}+(?:aA|bB)', 'bBbBbBbBbB', FALSE}, + {'(?:aA)?+(?:aA)', 'aAb', FALSE}, + {'(aA)?+(aA)', 'aAb', FALSE}, + {'(aA|bB)?+(aA|bB)', 'bBb', FALSE}, + {'(?:aA|bB)?+(?:aA|bB)', 'aAb', FALSE}, + {'(?:aA)++b', 'aAaAaAaAaAb', TRUE}, + {'(aA)++b', 'aAaAaAaAaAb', TRUE}, + {'(aA|bB)++b', 'aAbBaAaAbBb', TRUE}, + {'(?:aA|bB)++b', 'aAbBbBaAaAb', TRUE}, + {'(?:aA)*+b', 'aAaAaAaAaAb', TRUE}, + {'(aA)*+b', 'aAaAaAaAaAb', TRUE}, + {'(aA|bB)*+b', 'bBbBbBbBbBb', TRUE}, + {'(?:aA|bB)*+b', 'bBaAbBbBaAb', TRUE}, + {'(?:aA){1,5}+b', 'aAaAaAaAaAb', TRUE}, + {'(aA){1,5}+b', 'aAaAaAaAaAb', TRUE}, + {'(aA|bB){1,5}+b', 'bBaAbBaAbBb', TRUE}, + {'(?:aA|bB){1,5}+b', 'aAbBaAbBbBb', TRUE}, + {'(?:aA)?+b', 'aAb', TRUE}, + {'(aA)?+b', 'aAb', TRUE}, + {'(aA|bB)?+b', 'bBb', TRUE}, + {'(?:aA|bB)?+b', 'bBb', TRUE}, + {'foo(?:aA)++(?:aA)', 'fooaAaAaAaAaA', FALSE}, + {'foo(aA)++(aA)', 'fooaAaAaAaAaA', FALSE}, + {'foo(aA|bB)++(aA|bB)', 'foobBbBbBaAaA', FALSE}, + {'foo(?:aA|bB)++(?:aA|bB)', 'fooaAaAaAaAaA', FALSE}, + {'foo(?:aA)*+(?:aA)', 'fooaAaAaAaAaA', FALSE}, + {'foo(aA)*+(aA)', 'fooaAaAaAaAaA', FALSE}, + {'foo(aA|bB)*+(aA|bB)', 'foobBaAbBaAaA', FALSE}, + {'foo(?:aA|bB)*+(?:aA|bB)', 'fooaAaAbBbBaA', FALSE}, + {'foo(?:aA){1,5}+(?:aA)', 'fooaAaAaAaAaA', FALSE}, + {'foo(aA){1,5}+(aA)', 'fooaAaAaAaAaA', FALSE}, + {'foo(aA|bB){1,5}+(aA|bB)', 'fooaAbBbBaAaA', FALSE}, + {'foo(?:aA|bB){1,5}+(?:aA|bB)', 'fooaAbBbBaAbB', FALSE}, + {'foo(?:aA)?+(?:aA)', 'fooaAb', FALSE}, + {'foo(aA)?+(aA)', 'fooaAb', FALSE}, + {'foo(aA|bB)?+(aA|bB)', 'foobBb', FALSE}, + {'foo(?:aA|bB)?+(?:aA|bB)', 'fooaAb', FALSE}, + {'foo(?:aA)++b', 'fooaAaAaAaAaAb', TRUE}, + {'foo(aA)++b', 'fooaAaAaAaAaAb', TRUE}, + {'foo(aA|bB)++b', 'foobBaAbBaAbBb', TRUE}, + {'foo(?:aA|bB)++b', 'fooaAaAbBaAaAb', TRUE}, + {'foo(?:aA)*+b', 'fooaAaAaAaAaAb', TRUE}, + {'foo(aA)*+b', 'fooaAaAaAaAaAb', TRUE}, + {'foo(aA|bB)*+b', 'foobBbBaAaAaAb', TRUE}, + {'foo(?:aA|bB)*+b', 'foobBaAaAbBaAb', TRUE}, + {'foo(?:aA){1,5}+b', 'fooaAaAaAaAaAb', TRUE}, + {'foo(aA){1,5}+b', 'fooaAaAaAaAaAb', TRUE}, + {'foo(aA|bB){1,5}+b', 'foobBaAaAaAaAb', TRUE}, + {'foo(?:aA|bB){1,5}+b', 'fooaAbBaAbBbBb', TRUE}, + {'foo(?:aA)?+b', 'fooaAb', TRUE}, + {'foo(aA)?+b', 'fooaAb', TRUE}, + {'foo(aA|bB)?+b', 'foobBb', TRUE}, + {'foo(?:aA|bB)?+b', 'foobBb', TRUE}, + {'([^()]++|\\([^()]*\\))+', '((abc(ade)ufh()()x', TRUE}, + {'round\\(([^()]++)\\)', '_I(round(xs * sz),1)', TRUE}, + {'(foo[1x]|bar[2x]|baz[3x])+y', 'foo1bar2baz3y', TRUE}, + {'(foo[1x]|bar[2x]|baz[3x])*y', 'foo1bar2baz3y', TRUE}, + {'([yX].|WORDS|[yX].|WORD)S', 'WORDS', TRUE}, + {'([yX].|WORDS|WORD|[xY].)S', 'WORDS', TRUE}, + {'(foo|fool|[zx].|money|parted)$', 'fool', TRUE}, + {'([zx].|foo|fool|[zq].|money|parted|[yx].)$', 'fool', TRUE}, + {'(foo|fool|[zx].|money|parted)$', 'fools', FALSE}, + {'([zx].|foo|fool|[qx].|money|parted|[py].)$', 'fools', FALSE}, + {'([yX].|WORDS|[yX].|WORD)+S', 'WORDS', TRUE}, + {'(WORDS|WORLD|WORD)+S', 'WORDS', TRUE}, + {'([yX].|WORDS|WORD|[xY].)+S', 'WORDS', TRUE}, + {'(foo|fool|[zx].|money|parted)+$', 'fool', TRUE}, + {'([zx].|foo|fool|[zq].|money|parted|[yx].)+$', 'fool', TRUE}, + {'(foo|fool|[zx].|money|parted)+$', 'fools', FALSE}, + {'([zx].|foo|fool|[qx].|money|parted|[py].)+$', 'fools', FALSE}, + {'(x|y|z[QW])+(longish|loquatious|excessive|overblown[QW])+', 'xyzQzWlongishoverblownW', TRUE}, + {'(x|y|z[QW])*(longish|loquatious|excessive|overblown[QW])*', 'xyzQzWlongishoverblownW', TRUE}, + {'(x|y|z[QW]){1,5}(longish|loquatious|excessive|overblown[QW]){1,5}', 'xyzQzWlongishoverblownW', TRUE}, + {'(x|y|z[QW])++(longish|loquatious|excessive|overblown[QW])++', 'xyzQzWlongishoverblownW', TRUE}, + {'(x|y|z[QW])*+(longish|loquatious|excessive|overblown[QW])*+', 'xyzQzWlongishoverblownW', TRUE}, + {'(x|y|z[QW]){1,5}+(longish|loquatious|excessive|overblown[QW]){1,5}+', 'xyzQzWlongishoverblownW', TRUE}, + {'a*(?!)', 'aaaab', FALSE}, + {'a*(*FAIL)', 'aaaab', FALSE}, + {'a*(*F)', 'aaaab', FALSE}, + {'(A(A|B(*ACCEPT)|C)D)(E)', 'AB', TRUE}, + {'(A(A|B(*ACCEPT)|C)D)(E)', 'ACDE', TRUE}, + {'(a)(?:(?-1)|(?+1))(b)', 'aab', TRUE}, + {'(a)(?:(?-1)|(?+1))(b)', 'abb', TRUE}, + {'(a)(?:(?-1)|(?+1))(b)', 'acb', FALSE}, + {'(foo)(\\g-2)', 'foofoo', TRUE}, + {'(foo)(\\g-2)(foo)(\\g-2)', 'foofoofoofoo', TRUE}, + {'(([abc]+) \\g-1)(([abc]+) \\g{-1})', 'abc abccba cba', TRUE}, + {'(a)(b)(c)\\g1\\g2\\g3', 'abcabc', TRUE}, + {'(?<=bar>)foo', 'bar>foo', TRUE}, + {'(?)foo', 'bar>foo', FALSE}, + {'(?<=bar>ABC)foo', 'bar>ABCfoo', TRUE}, + {'(?ABC)foo', 'bar>ABCfoo', FALSE}, + {'(?)foo', 'bar>ABCfoo', TRUE}, + {'(?ABC)foo', 'bar>ABCfoo', TRUE}, + {'(?<=abcd(?<=(aaaabcd)))', '..aaaabcd..', TRUE}, + {'(?=xy(?<=(aaxy)))', '..aaxy..', TRUE}, + {'X(\\w+)(?=\\s)|X(\\w+)', 'Xab', TRUE}, + {'(?|(a))', 'a', TRUE}, + {'(?|a(.)b|d(.(o).)d|i(.)(.)j)(.)', 'd!o!da', TRUE}, + {'(?|a(.)b|d(.(o).)d|i(.)(.)j)(.)', 'aabc', TRUE}, + {'(?|a(.)b|d(.(o).)d|i(.)(.)j)(.)', 'ixyjp', TRUE}, + {'(?|(?|(a)|(b))|(?|(c)|(d)))', 'a', TRUE}, + {'(?|(?|(a)|(b))|(?|(c)|(d)))', 'b', TRUE}, + {'(?|(?|(a)|(b))|(?|(c)|(d)))', 'c', TRUE}, + {'(?|(?|(a)|(b))|(?|(c)|(d)))', 'd', TRUE}, + {'(.)(?|(.)(.)x|(.)d)(.)', 'abcde', TRUE}, + {'(\n)(?|(\n)(\n)x|(\n)d)(\n)', 'abcde', TRUE}, + {'(?|(?x))', 'x', TRUE}, + {'(?)(?|(?x))', 'x', TRUE}, + {'(?|(b)|()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()(a))', 'a', TRUE}, + {'(?(DEFINE)(?(?&B)+)(?a))(?&A)', 'a', TRUE}, + {'(?(DEFINE)(?(?&B)+)(?a))(?&A)', 'aa', TRUE}, + {'foo(\\R)bar', 'foo\\r\nbar', TRUE}, + {'foo(\\R)bar', 'foo\nbar', TRUE}, + {'foo(\\R)bar', 'foo\\rbar', TRUE}, + {'foo(\\R+)bar', 'foo\\r\n\\x{85}\\r\n\nbar', TRUE}, + {'(\\V+)(\\R)', 'foo\\r\n\\x{85}\\r\n\nbar', TRUE}, + {'(\\R+)(\\V)', 'foo\\r\n\\x{85}\\r\n\nbar', TRUE}, + {'foo(\\R)bar', 'foo\\x{85}bar', TRUE}, + {'(\\V)(\\R)', 'foo\\x{85}bar', TRUE}, + {'(\\R)(\\V)', 'foo\\x{85}bar', TRUE}, + {'(\\V)(\\R)', 'foo\\r\nbar', TRUE}, + {'(\\R)(\\V)', 'foo\\r\nbar', TRUE}, + {'(\\V)(\\R)', 'foo\\rbar', TRUE}, + {'(\\R)(\\V)', 'foo\\rbar', TRUE}, + {'0|\\R??\n0', '\n\n', FALSE}, + {'foo(\\v+)bar', 'foo\\r\n\\x{85}\\r\n\nbar', TRUE}, + {'(\\v+)(\\V)', 'foo\\r\n\\x{85}\\r\n\nbar', TRUE}, + {'foo(\\v)bar', 'foo\\x{85}bar', TRUE}, + {'(\\v)(\\V)', 'foo\\x{85}bar', TRUE}, + {'foo(\\v)bar', 'foo\\rbar', TRUE}, + {'(\\v)(\\V)', 'foo\\rbar', TRUE}, + {'foo(\\h+)bar', 'foo\\t\\x{A0}bar', TRUE}, + {'(\\h+)(\\H)', 'foo\\t\\x{A0}bar', TRUE}, + {'foo(\\h)bar', 'foo\\x{A0}bar', TRUE}, + {'(\\h)(\\H)', 'foo\\x{A0}bar', TRUE}, + {'foo(\\h)bar', 'foo\\tbar', TRUE}, + {'(\\h)(\\H)', 'foo\\tbar', TRUE}, + {'.*\\z', 'foo\n', TRUE}, + {'\n*\\z', 'foo\n', TRUE}, + {'^(?:(\\d)x)?\\d$', '1', TRUE}, + {'.*?(?:(\\w)|(\\w))x', 'abx', TRUE}, + {'0{50}', '000000000000000000000000000000000000000000000000000', TRUE}, + {'^a?(?=b)b', 'ab', TRUE}, + {'^a*(?=b)b', 'ab', TRUE}, + {'[\\s][\\S]', '\\x{a0}\\x{a0}', FALSE}, + {'abc\n\\{U+BEEF\\}', 'abc.{UBEEF}', TRUE}, + {'abc\n', 'abcd', TRUE}, + {'abc\n', 'abc\n', FALSE}, + {'\\c@', '\\0', TRUE}, + {'\\cA', '\\001', TRUE}, + {'\\cB', '\\002', TRUE}, + {'\\cC', '\\003', TRUE}, + {'\\cI', '\\011', TRUE}, + {'\\cJ', '\\012', TRUE}, + {'\\cR', '\\022', TRUE}, + {'\\cS', '\\023', TRUE}, + {'\\cX', '\\030', TRUE}, + {'\\cY', '\\031', TRUE}, + {'\\cZ', '\\032', TRUE}, + {'\\c[', '\\033', TRUE}, + {'\\c\\X', '\\034X', TRUE}, + {'\\c]', '\\035', TRUE}, + {'\\c^', '\\036', TRUE}, + {'\\c_', '\\037', TRUE}, + {'\\o{120}', '\\x{50}', TRUE}, + {'[a\\o{120}]', '\\x{50}', TRUE}, + {'[\\006]', '\\006', TRUE}, + {'[\\006]', '6\\000', FALSE}, + {'[\\0005]', '\\0005', TRUE}, + {'[\\0005]', '5\\000', TRUE}, + {'[\\_]', '_', TRUE}, + {'(q1|.)*(q2|.)*(x(a|bc)*y){2,}', 'xayxay', TRUE}, + {'(q1|.)*(q2|.)*(x(a|bc)*y){2,3}', 'xayxay', TRUE}, + {'(q1|z)*(q2|z)*z{15}-.*?(x(a|bc)*y){2,3}Z', 'zzzzzzzzzzzzzzzz-xayxayxayxayZ', TRUE}, + {'(?:(?:)foo|bar|zot|rt78356)', 'foo', TRUE}, + {'^m?(\\S)(.*)\\1$', 'aba', TRUE}, + {'^m?(\\S)(.*)\\1$', '\\tb\\t', FALSE}, + {'^m?(\\s)(.*)\\1$', '\\tb\\t', TRUE}, + {'^m?(\\s)(.*)\\1$', 'aba', FALSE}, + {'^m?(\\W)(.*)\\1$', ':b:', TRUE}, + {'^m?(\\W)(.*)\\1$', 'aba', FALSE}, + {'^m?(\\w)(.*)\\1$', 'aba', TRUE}, + {'^m?(\\w)(.*)\\1$', ':b:', FALSE}, + {'^m?(\\D)(.*)\\1$', 'aba', TRUE}, + {'^m?(\\D)(.*)\\1$', '5b5', FALSE}, + {'^m?(\\d)(.*)\\1$', '5b5', TRUE}, + {'^m?(\\d)(.*)\\1$', 'aba', FALSE}, + {'^_?[^\\W_0-9]\\w\\z', '\\xAA\\x{100}', TRUE}, + {'(?#( (?{1+)a', 'a', TRUE}, + {'ab[(?{1]', 'ab1', TRUE}, + {'ab[(?{1\\](?{2]', 'ab2', TRUE}, + {'[^\\p{Alphabetic}]', '\\x{100}', FALSE}, + {'^(.)(?:(..)|B)[CX]', 'ABCDE', TRUE}, + {'^(.)(?:BC(.)|B)[CX]', 'ABCDE', TRUE}, + {'^(.)(?:(.)+)*[BX]', 'ABCDE', TRUE}, + {'^(.)(BC)*', 'ABCDE', TRUE}, + {'^(.)(BC)*[BX]', 'ABCDE', TRUE}, + {'^(.)(B)*.[DX]', 'ABCDE', TRUE}, + {'^(.)(B)*.[CX]', 'ABCDE', TRUE}, + {'^(?:(X)?(\\d)|(X)?(\\d\\d))$', 'X12', TRUE}, + {'^(?:(XX)?(\\d)|(XX)?(\\d\\d))$', 'XX12', TRUE}, + {'\\A(?>\\[(?:(?:)(?:R){1}|T|V?|A)\\])\\z', '[A]', TRUE}, + {'[^\n]+', '\nb', TRUE}, + {'[^\n]+', 'a\n', TRUE}, + {'\\w', '\\x{200C}', TRUE}, + {'\\W', '\\x{200C}', FALSE}, + {'\\w', '\\x{200D}', TRUE}, + {'\\W', '\\x{200D}', FALSE}, + {'^\\R{2}$', '\\r\n\\r\n', TRUE}, + {'\\Vn', '\\xFFn/', TRUE}, + {'^_?[^\\S_0-9]\\w*\\z', '\\t', TRUE}, + {'a?\\X', 'a\\x{100}', TRUE}, + {'a?\\R', 'a\n', TRUE}, + {'^a?\n$', 'a\n', TRUE}, + {'\n?a', '\na', TRUE}, + {'(A(*PRUNE)B|A(*PRUNE)C)', 'AC', FALSE}, + {'(A(*PRUNE)B|A(*PRUNE)D|A(*PRUNE)C)', 'AC', FALSE}, + {'(A(*PRUNE)B|A(*PRUNE)C|A(*PRUNE)D)', 'AC', FALSE}, + {'((A(*PRUNE)B|A(*PRUNE)C))', 'AC', FALSE}, + {'((A(*PRUNE)B|A(*PRUNE)D|A(*PRUNE)C))', 'AC', FALSE}, + {'((A(*PRUNE)B|A(*PRUNE)C|A(*PRUNE)D))', 'AC', FALSE}, + {'A+?(*THEN)BC', 'AAABC', TRUE}, + {'A+?(*PRUNE)BC', 'AAABC', TRUE}, + {'A+(*THEN)BC', 'AAABC', TRUE}, + {'A+(*PRUNE)BC', 'AAABC', TRUE}, + {'^(?=(a)){0}b(?1)', 'back', TRUE}, + {'(?:(a(*SKIP)b)){0}(?:(?1)|ac)', 'x', FALSE}, + {'(?1)(?:(b)){0}', 'b', TRUE}, + {'(?a)(?(?=(?&W))(?<=(?&W)))(?&BB)', 'aa', TRUE}, + {'^x?abc?de', 'abcde', TRUE}, + {'\'(?-m:^abc)\'m', 'abcde', TRUE}, + {'\'(?-m:^abc)\'m', 'x\nabcde', FALSE}, + {'\\d<(.*?)>', 'a<>', FALSE}, + {'[bcd].{2,3}aaaa', 'XbXaaaaa', TRUE}, + {'[bcd].{2,3}aaaa', 'Xb\\x{100}aaaaa', TRUE}, + {'\'\\Awibble\\z\'m', 'wibble', TRUE}, + {'^((?(?=x)xb|ya)z)', 'xbz', TRUE}, + {'^((?(?=x)xb|ya)z)', 'yaz', TRUE}, + {'^((?(?!y)xb|ya)z)', 'xbz', TRUE}, + {'^((?(?!y)xb|ya)z)', 'yaz', TRUE}, + {'^((?(?!)xb|ya)z)', 'xbz', FALSE}, + {'^((?(?!)xb|ya)z)', 'yaz', TRUE}, + {'ab(?#Comment){2}c', 'abbc', TRUE}, + {'(?:.||)(?|)000000000@', '000000000@', TRUE}, + {'aa$|a(?R)a|a', 'aaa', TRUE}, + {'(?:\\1|a)([bcd])\\1(?:(?R)|e)\\1', 'abbaccaddedcb', TRUE}, + {'(.*?(a(a)|i(i))n)', 'riiaan', TRUE}, + {'(^(?:(\\d)x)?\\d$)', '1', TRUE}, + {'(X{2,}[-X]{1,4}){3,}X{2,}', 'XXX-XXX-XXX--', FALSE}, + {'^a?bcd\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', FALSE}, + {'^Xaaa?Xaa', 'aaa\\x{400000}', FALSE}, + {'^(\\d+)*?4X$', '1234X', TRUE}, + {'\\A([\\x00-\\x7F]+)(.*)\\z', '\\007\\011\\012', TRUE}, + {'^((\\w|<(\\s)*(?1)(?3)*>)(?:(?3)*\\+(?3)*(?2))*)(?3)*\\+', 'a + b + ', TRUE}, + {'^((\\w|<(\\s)*(?1)(?3)*>)(?:(?3)*\\+(?3)*(?2))*)(?3)*\\+', 'a + + c', TRUE}, + {'(?<=(?