c++ - std::regex:匹配由数字和空格组成的字符串,并提取数字。怎么样?

标签 c++ regex

我想同时做两件事:将字符串与模式匹配并提取组。

字符串由空格和数字组成。我想将字符串与此模式匹配。另外,我想使用std::smatch提取数字(不是数字,仅是一位数字)。

我尝试了很多,但没有成功。

对于骗子猎人:我检查了许多关于SO的答案,但找不到解决方案。

然后,我尝试使用std::sregex_token_iterator。结果也让我感到困惑。在

#include <string>
#include <regex>
#include <vector>
#include <iterator>

const std::regex re1{ R"(((?:\s*)|(\d))+)" };

const std::regex re2{ R"(\s*(\d)\s*)" };

int main() {
    std::string test("   123 45 6   ");
    std::smatch sm;

    bool valid1 = std::regex_match(test, sm, re1);
    std::vector<std::string> v(std::sregex_token_iterator(test.begin(), test.end(), re2), {});
    return 0;
}

vector 不仅包含数字,还包含空格。我只想输入数字。
smatch不包含任何数字。

我知道,我可以先从字符串中删除所有空格,但是应该有一个更好的一步解决方案。

1.将字符串与我描述的模式匹配,然后2.将所有单个数字提取到smatch中,正确的正则表达式是什么?

最佳答案

您需要验证的模式是

\s*(?:\d\s*)*

请参阅regex demo(请注意,我在regex测试站点上添加了^$以使模式匹配整个字符串,因为您在代码中使用了等效的regex_match,因此需要完整的字符串匹配)。

接下来,一旦使用第一个正则表达式验证了您的字符串,您只需要提取任何一位数字即可:
const std::regex re2{ R"(\d)" };
// ...
std::vector<std::string> v(std::sregex_token_iterator(test.begin(), test.end(), re2), {});

完整working snippet:
#include <string>
#include <regex>
#include <vector>
#include <iterator>
#include <iostream>

const std::regex re1{ R"(\s*(?:\d\s*)*)" };

const std::regex re2{ R"(\d)" };

int main() {
    std::string test("   123 45 6   ");
    std::smatch sm;

    bool valid1 = std::regex_match(test, sm, re1);
    std::vector<std::string> v(std::sregex_token_iterator(test.begin(), test.end(), re2), {});
    for (auto i: v)
        std::cout << i << std::endl;

    return 0;
}

输出:
1
2
3
4
5
6

使用Boost 的替代解决方案

仅当整个字符串由空格和数字组成时,才可以使用将单独匹配所有数字的正则表达式,使用
\G\s*(\d)(?=[\s\d]*$)

参见regex demo

详细信息
  • \G-字符串的开头或前面成功匹配的结尾
  • \s*-0+空格
  • (\d)-组1中捕获的数字(当将1作为boost::sregex_token_iterator iter(test.begin(), test.end(), re2, 1)中的最后一个参数传递时,我们将仅返回此值)
  • (?=[\s\d]*$)-必须有0个或多个空格或数字,然后紧接当前位置右侧的字符串结尾。

  • 请参阅whole C++ snippet(与-lboost_regex选项一起编译):
    #include <iostream>
    #include <vector>
    #include <boost/regex.hpp>
    
    int main()
    {
        std::string test("   123 45 6   ");
        boost::regex re2(R"(\G\s*(\d)(?=[\s\d]*$))");
        boost::sregex_token_iterator iter(test.begin(), test.end(), re2, 1);
        boost::sregex_token_iterator end;
        std::vector<std::string> v(iter, end);
        for (auto i: v)
            std::cout << i << std::endl;
    
        return 0;
    }
    

    关于c++ - std::regex:匹配由数字和空格组成的字符串,并提取数字。怎么样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62370866/

    相关文章:

    c++ - 无法链接 GLFW3 : undefined references

    c++ - 从 std::scoped_lock 抛出的异常

    regex - Gorilla Mux Regex 用于范围和预定义选项之间的数字

    regex - LibXML中的xPath可以是正则表达式类型吗

    ruby - 使用正则表达式找不到哈希键值

    c++ - boost 的正则表达式无法编译

    java - 如何只替换标记,没有子字符串?

    C++ 标准库 : initialize a container by using standard input

    2行相同长度的C++算法

    c++ - 如何从 vtkDataArray 获取 VTK 的元组大小