仅在最后一次出现捕获组时才使字符可选

时间:2019-04-06 22:32:45

标签: c++ regex

我正在尝试在C ++应用程序中使用正则表达式来测试字符串是否与常见的数组类型格式匹配。该字符串应与用逗号分隔的数字列表匹配,并用任意数量的空格字符包围并用花括号将其括起来。因此,

 {1, 2, 3}`, 
 {12.234,2313.4231, 
 {+1.232, -2313.32,    12} 

应全部正确匹配。我当前的正则表达式字符串是这个(为清楚起见添加了空格):

\\{ ( \\s*?[+-]?[0-9]+\\.?[0-9]?,\\s*? )+ \\}

此字符串的问题是,在每个数字后必需,以便被视为有效字符串。也就是说,字符串{12, 12, 12,}有效,但是由于缺少最后一个逗号,因此字符串{12, 12, 12}不匹配。我可以通过在其后添加一个?来使逗号为可选,但这会使字符串{12 12 12}有效,我想避免这种情况。

我应该如何使逗号字符仅在字符串中 last 出现时是可选的?

下面是说明我的问题的代码段:

#include <iostream>
#include <string>
#include <regex>

int main()
{
    std::regex test("\\{(\\s*?[+-]?[0-9]+\\.?[0-9]?,\\s*?)+\\}");
    std::string input;
    while(1){
        std::getline(std::cin, input);
        if(input == "exit")
            break;
        if(std::regex_match(input, test))
            std::cout << "string matches" << std::endl;
        else
            std::cout << "string does not match" << std::endl;
    }
}

1 个答案:

答案 0 :(得分:1)

如果您在顶部提到的三个字符串({1, 2, 3}{12.234,2313.4231,}{+1.232, -2313.32, 12})是有效的,则可以使用两种方法:带有正向超前的交替,将检查是否存在在末尾是}(?:,\\s*|(?=\\}$))

std::regex test("\\{(?:\\s*[+-]?[0-9]+\\.?[0-9]*(?:,\\s*|(?=\\}$)))+\\}");

或在最后一个,?之前添加可选的逗号}

std::regex test("\\{\\s*[+-]?[0-9]+\\.?[0-9]*(?:,\\s*[+-]?[0-9]+\\.?[0-9]*)*\\s*,?\\}");

请参见regex demo 1regex demo 2

如果{1, 2, 3,}无效,最好的方法是解开重复的组:

std::regex test("\\{\\s*[+-]?[0-9]+\\.?[0-9]*(?:,\\s*[+-]?[0-9]+\\.?[0-9]*)*\\s*\\}"); 

请参见this regex demo