在 C++ 中使用 regex/boost 查找 2 个数字之间的数字

Posted

技术标签:

【中文标题】在 C++ 中使用 regex/boost 查找 2 个数字之间的数字【英文标题】:Finding a number between 2 numbers using regex/boost in c++ 【发布时间】:2015-05-21 17:59:40 【问题描述】:

我觉得这是一个非常基本的问题,但我没有找到关于它的帖子。如果你知道一个,请在下面链接它。 所以我要做的是查看一个字符串并以 2 个为一组提取数字。

这是我的代码:

int main() 
        string line = "P112233";
        boost::regex e ("P([0-9]2[0-9]2[0-9]2)");
        boost::smatch match;

        if (boost::regex_search(line, match, e))
        
            boost::regex f("([0-9]2)"); //finds 11
            boost::smatch match2;
            line = match[0];
            if (boost::regex_search(line, match2, f))
            
                float number1 = boost::lexical_cast<float>(match2[0]);
                cout << number1 << endl;  // this works and prints out 11.
            

            boost::regex g("         "); // here I want it to find the 22
            boost::smatch match3;
            if (boost::regex_search(line, match3, g))
            
                float number2 = boost::lexical_cast<float>(match3[0]);
                cout << number2 << endl;
            
            boost::regex h("         "); // here I want it to find the 33
            boost::smatch match4;
            if (boost::regex_search(line, match4, h))
            
                float number3 = boost::lexical_cast<float>(match4[0]);
                cout << number3 << endl;
            
        
        else
            cout << "found nothing"<< endl;
    return 0;

我能够获得第一个数字,但我不知道如何获得第二个(22)和第三个(33)。 我需要使用的正确表达方式是什么?

【问题讨论】:

如果您使用 3 个捕获组(即"P([0-9]2)([0-9]2)([0-9]2)"),那么您可以访问match[i],其中i 是您要提取的组的编号(我相信match[0] 是整个匹配的字符串)。 是的,match[0] 是整个字符串。我想我明白你的意思,但我以前从未使用过捕获组。 match[1, 2, 3 etc.] 什么都没有。我不断收到此错误terminate called after throwing an instance of 'boost::exception_detail::clone_impl&lt;boost::exception_detail::error_info_injector&lt;boost::bad_lexical_cast&gt; &gt;' what(): bad lexical cast: source type value could not be interpreted as target 你能给我更多信息吗? 【参考方案1】:

正如@Cornstalks 提到的,您需要使用 3 个捕获组,然后您可以像这样访问它们:

int main() 

    std::string line = "P112233";
    boost::regex e("P([0-9]2)([0-9]2)([0-9]2)");
    boost::smatch match;

    if (boost::regex_search(line, match, e))
    
        std::cout << match[0] << std::endl; // prints the whole string
        std::cout << match[1] << ", " << match[2] << ", " << match[3] << std::endl;
    

    return 0;

输出:

P112233
11, 22, 33

【讨论】:

太棒了!非常感谢!你能告诉我 .first 和 .second 是干什么用的吗? @KH17 .first 和 .second 是指向字符串开头和结尾的迭代器。 @doqtor 不需要这些:str() is easier,或者实际上是use the implicit conversion,或者实际上为什么分配at all。但话又说回来,我不会在这里使用正则表达式。见my answer【参考方案2】:

我不赞成这种解析的正则表达式。关键是当你完成那个毛茸茸的正则表达式插曲时,数字仍然是字符串。

我会在这里改用 Boost Spirit,它会一次性解析成所有数字,而且您甚至不必链接到 Boost Regex 库,因为 Spirit 仅是标题。

Live On Coliru

#include <boost/spirit/include/qi.hpp>
#include <iostream>

namespace qi = boost::spirit::qi;
static qi::int_parser<int, 10, 2, 2> two_digits;

int main() 
    std::string const s = "P112233";

    std::vector<int> nums;
    if (qi::parse(s.begin(), s.end(), "P" >> *two_digits, nums))
    
        std::cout << "Parsed " << nums.size() << " pairs of digits:\n";
        for(auto i : nums)
            std::cout << " * " << i << "\n";
    



Parsed 3 pairs of digits:
 * 11
 * 22
 * 33

【讨论】:

以上是关于在 C++ 中使用 regex/boost 查找 2 个数字之间的数字的主要内容,如果未能解决你的问题,请参考以下文章

尝试在 C++ 中使用 boost 正则表达式匹配从字符串转换为 int 时出错

如何使用 C++ 在 Windows 中使用更改日志查找文件修改

使用 VS Code 在 C++ 应用程序中查找内存泄漏

使用 gnu coreutils 在 C++ 中查找包含保护错别字

如何在 Visual C++ 2008 中查找未使用的属性/方法

在 C++ 中使用正则表达式查找 [/ 和 ] 之间的数字