diff --git a/libcxx/include/regex b/libcxx/include/regex --- a/libcxx/include/regex +++ b/libcxx/include/regex @@ -2837,6 +2837,8 @@ __parse_awk_escape(_ForwardIterator __first, _ForwardIterator __last, basic_string<_CharT>* __str = nullptr); + bool __test_back_ref(_CharT c); + _LIBCPP_INLINE_VISIBILITY void __push_l_anchor(); void __push_r_anchor(); @@ -3408,18 +3410,8 @@ if (__first != __last) { _ForwardIterator __temp = _VSTD::next(__first); - if (__temp != __last) - { - if (*__first == '\\') - { - int __val = __traits_.value(*__temp, 10); - if (__val >= 1 && __val <= 9) - { - __push_back_ref(__val); - __first = ++__temp; - } - } - } + if (__temp != __last && *__first == '\\' && __test_back_ref(*__temp)) + __first = ++__temp; } return __first; } @@ -3547,6 +3539,8 @@ default: if (__get_grammar(__flags_) == awk) __first = __parse_awk_escape(++__first, __last); + else if(__test_back_ref(*__temp)) + __first = ++__temp; break; } } @@ -4661,6 +4655,20 @@ } template +bool +basic_regex<_CharT, _Traits>::__test_back_ref(_CharT c) +{ + unsigned __val = __traits_.value(c, 10); + if (__val >= 1 && __val <= 9) + { + __push_back_ref(__val); + return true; + } + + return false; +} + +template void basic_regex<_CharT, _Traits>::__push_loop(size_t __min, size_t __max, __owns_one_state<_CharT>* __s, size_t __mexp_begin, size_t __mexp_end, diff --git a/libcxx/test/std/re/re.alg/re.alg.match/extended.pass.cpp b/libcxx/test/std/re/re.alg/re.alg.match/extended.pass.cpp --- a/libcxx/test/std/re/re.alg/re.alg.match/extended.pass.cpp +++ b/libcxx/test/std/re/re.alg/re.alg.match/extended.pass.cpp @@ -432,6 +432,24 @@ { std::cmatch m; const char s[] = "-ab,ab-"; + assert(std::regex_match(s, m, std::regex("-(.*),\\1-", std::regex_constants::extended))); + assert(m.size() == 2); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == m[0].second); + assert(m.length(0) >= 0 && static_cast(m.length(0)) == std::char_traits::length(s)); + assert(m.position(0) == 0); + assert(m.str(0) == s); + assert(m.length(1) == 2); + assert(m.position(1) == 1); + assert(m.str(1) == "ab"); + } + { + std::cmatch m; + const char s[] = "-ab,ab-"; assert(std::regex_match(s, m, std::regex("-.*,.*-", std::regex_constants::extended))); assert(m.size() == 1); assert(!m.prefix().matched); @@ -1098,6 +1116,24 @@ { std::wcmatch m; const wchar_t s[] = L"-ab,ab-"; + assert(std::regex_match(s, m, std::wregex(L"-(.*),\\1-", std::regex_constants::extended))); + assert(m.size() == 2); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == m[0].second); + assert(m.length(0) >= 0 && static_cast(m.length(0)) == std::char_traits::length(s)); + assert(m.position(0) == 0); + assert(m.str(0) == s); + assert(m.length(1) == 2); + assert(m.position(1) == 1); + assert(m.str(1) == L"ab"); + } + { + std::wcmatch m; + const wchar_t s[] = L"-ab,ab-"; assert(std::regex_match(s, m, std::wregex(L"-.*,.*-", std::regex_constants::extended))); assert(m.size() == 1); assert(!m.prefix().matched); diff --git a/libcxx/test/std/re/re.alg/re.alg.search/extended.pass.cpp b/libcxx/test/std/re/re.alg/re.alg.search/extended.pass.cpp --- a/libcxx/test/std/re/re.alg/re.alg.search/extended.pass.cpp +++ b/libcxx/test/std/re/re.alg/re.alg.search/extended.pass.cpp @@ -495,6 +495,24 @@ { std::cmatch m; const char s[] = "-ab,ab-"; + assert(std::regex_search(s, m, std::regex("-(.*),\\1-", std::regex_constants::extended))); + assert(m.size() == 2); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == m[0].second); + assert(m.length(0) >= 0 && static_cast(m.length(0)) == std::char_traits::length(s)); + assert(m.position(0) == 0); + assert(m.str(0) == s); + assert(m.length(1) == 2); + assert(m.position(1) == 1); + assert(m.str(1) == "ab"); + } + { + std::cmatch m; + const char s[] = "-ab,ab-"; assert(std::regex_search(s, m, std::regex("-.*,.*-", std::regex_constants::extended))); assert(m.size() == 1); assert(!m.prefix().matched); @@ -1251,6 +1269,24 @@ { std::wcmatch m; const wchar_t s[] = L"-ab,ab-"; + assert(std::regex_search(s, m, std::wregex(L"-(.*),\\1-", std::regex_constants::extended))); + assert(m.size() == 2); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == m[0].second); + assert(m.length(0) >= 0 && static_cast(m.length(0)) == std::char_traits::length(s)); + assert(m.position(0) == 0); + assert(m.str(0) == s); + assert(m.length(1) == 2); + assert(m.position(1) == 1); + assert(m.str(1) == L"ab"); + } + { + std::wcmatch m; + const wchar_t s[] = L"-ab,ab-"; assert(std::regex_search(s, m, std::wregex(L"-.*,.*-", std::regex_constants::extended))); assert(m.size() == 1); assert(!m.prefix().matched);