我在C ++中尝试正则表达式,这里有一些代码
#include <iostream>
#include <regex>
int main (int argc, char *argv[]) {
std::regex pattern("[a-z]+", std::regex_constants::icase);
std::regex pattern2("excelsior", std::regex_constants::icase);
std::string text = "EXCELSIOR";
if (std::regex_match(text, pattern)) std::cout << "works" << std::endl;
else std::cout << "doesn't work" << std::endl;
if (std::regex_match(text, pattern2)) std::cout << "works" << std::endl;
else std::cout << "doesn't work" << std::endl;
return 0;
}
现在,根据我的理解,这两个匹配应输出works
,但第一个输出doesn't work
,而第二个输出works
按预期输出。为什么呢?
答案 0 :(得分:2)
根据[re.grammar]中描述的规则,我们有:
- 在正则表达式有限状态机与字符序列匹配期间,两个 使用以下规则比较字符
c
和d
:
1.(flags() & regex_constants::icase)
traits_inst.translate_nocase(c) == traits_inst.translate_nocase(d)
如果flags() & regex_constants::collate
,则两个字符相等; 2.否则,traits_inst.translate(c) == traits_inst.translate(d);
c == d
如果pattern2
,则两个字符相等 3.否则,如果flags() & icase
,则两个字符相等。
这适用于您的pattern
,我们匹配一系列字符,我们有c1-c2
,因此我们进行了一次比较。由于序列中的每个字符都匹配,因此&#34;工作&#34;。
但是,对于c
,我们没有一系列字符。所以我们改为使用这条规则:
- 在正则表达式有限状态机与字符序列匹配期间,比较 对角色
flags() & regex_constants::collate
的整理元素范围c
的执行方式如下:如果c1 <= c && c <= c2
为false,则c
符合string_type str1 = string_type(1, flags() & icase ? traits_inst.translate_nocase(c1) : traits_inst.translate(c1); string_type str2 = string_type(1, flags() & icase ? traits_inst.translate_nocase(c2) : traits_inst.translate(c2); string_type str = string_type(1, flags() & icase ? traits_inst.translate_nocase(c) : traits_inst.translate(c); return traits_inst.transform(str1.begin(), str1.end()) <= traits_inst.transform(str.begin(), str.end()) && traits_inst.transform(str.begin(), str.end()) <= traits_inst.transform(str2.begin(), str2.end());
}, 除此以外collate
根据以下算法进行匹配:a-z
由于您没有设置icase
,因此字符在字面上与collate
范围匹配。这里没有std::regex pattern("[a-z]+",
std::regex_constants::icase | std::regex_constants::collate);
的解释,这就是为什么它不起作用。&#34;但是,如果您提供{{1}}:
{{1}}
然后我们使用所描述的算法,它将进行无案例比较,结果将是&#34;工作&#34;。两个编译器都是正确的 - 虽然我发现在这种情况下预期的行为令人困惑。
答案 1 :(得分:1)
std::regex pattern("[a-z]+", std::regex_constants::icase);
仍限制小写字母的模式匹配。我认为reference中提到的字符匹配似乎不适用于明确指定的字符集,这是我所期望的,如果明确指定则处理这些字符集是有意义的。
答案 2 :(得分:0)
问题是由区分大小写引起的:
http://coliru.stacked-crooked.com/a/ac21a962ee9f28fc
std::regex_constants::icase
忽略了标记std::regex_match
。
修改强>
添加标记std::regex_constants::collate
可以解决问题: