Я знаю это:
Ленивые совпадения квантификаторов: как можно меньше (самое короткое совпадение)
Также известно, что конструктор:
basic_regex( ...,
flag_type f = std::regex_constants::ECMAScript );
А также:
ECMAScript
опоры нежадным Матчи,
и ECMAScript
регулярное выражение "<tag[^>]*>.*?</tag>"
будет соответствовать только до первый закрывающий тег …
en.cppreference
А также:
Максимум один вариант грамматики должен быть выбран из ECMAScript
,
basic
, extended
, awk
, grep
, egrep
, Если грамматика не выбрана,
ECMAScript
предполагается быть выбранным …
en.cppreference
А также:
Обратите внимание, что regex_match
будет только успешно сопоставлять регулярное выражение для всей последовательности символов, тогда как std::regex_search
будет успешно соответствовать подпоследовательности …станд :: алгоритма regex_match
Вот мой код: + Жить
#include <iostream>
#include <string>
#include <regex>
int main(){
std::string string( "s/one/two/three/four/five/six/g" );
std::match_results< std::string::const_iterator > match;
std::basic_regex< char > regex ( "s?/.+?/g?" ); // non-greedy
bool test = false;
using namespace std::regex_constants;
// okay recognize the lazy operator .+?
test = std::regex_search( string, match, regex );
std::cout << test << '\n';
std::cout << match.str() << '\n';
// does not recognize the lazy operator .+?
test = std::regex_match( string, match, regex, match_not_bol | match_not_eol );
std::cout << test << '\n';
std::cout << match.str() << '\n';
}
и вывод:
1 s/one/ 1 s/one/two/three/four/five/six/g Process returned 0 (0x0) execution time : 0.008 s Press ENTER to continue.
std::regex_match
ничего не должно совпадать и должно возвращаться 0
с нежадным квантор .+?
На самом деле, здесь, нежадным .+?
квантификатор имеет то же значение, что и жадный один и оба /.+?/
а также /.+/
соответствовать одной и той же строке. Это разные модели.
Итак, проблема в том, почему знак вопроса игнорируется?
Быстрый тест:
$ echo 's/one/two/three/four/five/six/g' | perl -lne '/s?\/.+?\/g?/ && print $&'
$ s/one/
$
$ echo 's/one/two/three/four/five/six/g' | perl -lne '/s?\/.+\/g?/ && print $&'
$ s/one/two/three/four/five/six/g
НОТА
это регулярное выражение: std::basic_regex< char > regex ( "s?/.+?/g?" );
нежадным
и это : std::basic_regex< char > regex ( "s?/.+/g?" );
жадный
имеют одинаковый выход с std::regex_match
, Тем не менее оба соответствуют всей строке!
Но с std::regex_search
имеют разный выход.
Также s?
или же g?
не имеет значения и с /.*?/
по-прежнему соответствует всей строке!
Более детально
g++ --version
g++ (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901
Я не вижу противоречий. regex_match
пытается сопоставить всю строку, так s?/.+?/g?
лениво расширяется, пока вся строка не будет покрыта.
Эти «диаграммы» (для regex_search
надеюсь, поможет получить представление о жадности
Non-greedy:
a.*?a: ababa
a|.*?a: a|baba
a.*?|a: a|baba # ok, let's try .*? == "" first
# can't go further, backtracking
a.*?|a: ab|aba # lets try .*? == "b" now
a.*?a|: aba|ba
# If the regex were a.*?a$, there would be two extra backtracking
# steps such that .*? == "bab".
Greedy:
a.*?a: ababa
a|.*a: a|baba
a.*|a: ababa| # try .* == "baba" first
# backtrack
a.*|a: abab|a # try .* == "bab" now
a.*a|: ababa|
А также regex_match( abc )
как regex_search( ^abc$ )
в этом случае.
Других решений пока нет …