使用C ++ 11正则表达式匹配文本范围

时间:2015-08-13 17:07:52

标签: c++ regex c++11

我在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按预期输出。为什么呢?

3 个答案:

答案 0 :(得分:2)

根据[re.grammar]中描述的规则,我们有:

  

- 在正则表达式有限状态机与字符序列匹配期间,两个   使用以下规则比较字符cd
  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可以解决问题:

http://coliru.stacked-crooked.com/a/f57a2f2ff840c8be