[libc++] Fix std::regex_search to match $ alone with match_default flag (#78845)

Using std::regex_search with the regex_constant match_default and a
simple regex pattern `$` is expected to match general strings such as
_"a", "ab", "abc"..._ at `[last, last)` positions. But, the current
implementation fails to do so.

Fixes #75042
This commit is contained in:
Sanjay Marreddi
2024-01-22 19:15:05 +00:00
committed by GitHub
parent 6d5f8d3e6e
commit d83a3ea529
2 changed files with 47 additions and 0 deletions

View File

@@ -5124,6 +5124,14 @@ bool basic_regex<_CharT, _Traits>::__search(
}
__m.__matches_.assign(__m.size(), __m.__unmatched_);
}
__m.__matches_.assign(__m.size(), __m.__unmatched_);
if (__match_at_start(__first, __last, __m, __flags, false)) {
__m.__prefix_.second = __m[0].first;
__m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
__m.__suffix_.first = __m[0].second;
__m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;
return true;
}
}
__m.__matches_.clear();
return false;

View File

@@ -47,5 +47,44 @@ int main(int, char**)
assert( std::regex_search(target, re, std::regex_constants::match_not_eol));
}
{
std::string target = "foo";
std::regex re("$");
assert(std::regex_search(target, re));
assert(!std::regex_search(target, re, std::regex_constants::match_not_eol));
std::smatch match;
assert(std::regex_search(target, match, re));
assert(match.position(0) == 3);
assert(match.length(0) == 0);
assert(!std::regex_search(target, match, re, std::regex_constants::match_not_eol));
assert(match.length(0) == 0);
}
{
std::string target = "foo";
std::regex re("$", std::regex::multiline);
std::smatch match;
assert(std::regex_search(target, match, re));
assert(match.position(0) == 3);
assert(match.length(0) == 0);
assert(!std::regex_search(target, match, re, std::regex_constants::match_not_eol));
assert(match.length(0) == 0);
}
{
std::string target = "foo";
std::regex re("$");
assert(!std::regex_match(target, re));
assert(!std::regex_match(target, re, std::regex_constants::match_not_eol));
}
{
std::string target = "a";
std::regex re("^b*$");
assert(!std::regex_search(target, re));
assert(!std::regex_search(target, re, std::regex_constants::match_not_eol));
}
return 0;
}