代码之家  ›  专栏  ›  技术社区  ›  code_fodder

C++ 11(MsSv2012)ReX在多行STD::字符串中查找文件名

  •  2
  • code_fodder  · 技术社区  · 6 年前

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

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

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

    然后我想要火柴:

    • a_文件_123.xml
    • a_文件_j34.xml

    这是我的测试代码:

    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”…

    1 回复  |  直到 6 年前
        1
  •  3
  •   Wiktor Stribiżew    6 年前

    你只有一个对手,不是两个 regex_search 方法返回单个匹配项。你印的是两个 值,组0(整个匹配, a_file_123.xml 和组1(捕获组值,这里, 123 那是一个子串 捕获 你定义为 (.*) 在模式中)。

    如果要匹配多个字符串,则需要使用regex迭代器,而不仅仅是 正则搜索 只返回第一个匹配项。

    此外, .* 太贪婪了,如果同一行中有超过1个匹配项,则返回奇怪的结果。似乎你想匹配字母或数字,所以 * 可替换为 \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
    

    关于regex的注释

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

    regex demo