c++11 (MSVS2012) 正则表达式在多行中查找文件名 std::string

c++11 (MSVS2012) regex looking for file names in multiple line std::string

我一直在努力寻找关于这个问题的明确答案,但一直找不到。

所以假设我有字符串(其中 \n 可能是 \r\n - 我想处理两者 - 不确定这是否相关)

"4345t435\ng54t a_file_123.xml rk\ngreg a_file_j34.xml fger 43t54"

然后我想要匹配:

这是我的测试代码:

const str::string s = "4345t435\ng54t a_file_123.xml rk\ngreg a_file_j34.xml fger 43t54";

std::smatch matches;
if (std::regex_search(s, matches, std::regex("a_file_(.*)\.xml")))
{
    std::cout << "total: " << matches.size() << std::endl;
    for (unsigned int i = 0; i < matches.size(); i++)
    {
        std::cout << "match: " << matches[i] << std::endl;
    }
}

输出为:

total: 2
match: a_file_123.xml
match: 123

我不太明白为什么匹配 2 只是“123”...

您只有一场比赛,而不是两场比赛,因为 regex_search 方法 return 是一场比赛。您打印的是两个 group 值,第 0 组(整个匹配项,此处为 a_file_123.xml)和第 1 组(捕获组值,此处为 123一个子字符串 captured,其中包含您在模式中定义为 (.*) 的捕获组)。

如果你想匹配多个字符串,你需要使用正则表达式迭代器,而不是只 return 第一个匹配的 regex_search

此外,.* 过于贪婪,如果在同一行上有超过 1 个匹配项,将会 return 奇怪的结果。看来你要匹配字母或数字,所以 .* 可以用 \w+ 代替。嗯,如果真有什么,就用.*?.

使用

const std::string s = "4345t435\ng54t a_file_123.xml rk\ngreg a_file_j34.xml fger 43t54";
const std::regex rx("a_file_\w+\.xml");
std::vector<std::string> results(std::sregex_token_iterator(s.begin(), s.end(), rx),
                           std::sregex_token_iterator());

std::cout << "Number of matches: " << results.size() << std::endl;
for (auto result : results)
{
    std::cout << result << std::endl;
}

看到 C++ demo 屈服

Number of matches: 2
a_file_123.xml
a_file_j34.xml

关于正则表达式的注释

  • a_file_ - 文字子串
  • \w+ - 1+ 个单词字符(字母、数字、_)(请注意,如果您想匹配任何字符,可以在此处使用 [^.]*? 而不是 \w+ char,0 次或多次重复,尽可能少,直到第一个 .xml)
  • \. - 一个点(如果你不转义它,它将匹配除换行字符之外的任何字符)
  • xml - 文字子串。

regex demo