匹配和具有奇怪行为的懒惰量词
我知道:
惰性量词匹配:尽可能少(最短匹配)
也知道构造函数:
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
将成功匹配子序列... std :: regex_match
这是我的代码:+ Live
#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
与非贪婪量词.+?
事实上,在这里, 非贪婪的 .+?
量词与贪婪的意思相同,并且/.+?/
和/.+/
匹配相同的字符串。 他们是不同的模式。 所以问题是为什么问号被忽略?
regex101
快速测试:
$ 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$ )
。
上一篇: match and lazy quantifier with strange behavior
下一篇: JavaScript Alternative To Possessive Quantifiers In Dynamic Regex