【问题标题】:c++ regular expression matching whole linec++正则表达式匹配整行
【发布时间】:2012-03-09 08:14:09
【问题描述】:

我正在尝试解析包含数字数据的文本文件。我有很多看起来像的线条

129.3 72.7 121.6 173.6 203.3 120.7 40.5 79.2 94.0 123.2 165.8 178.8 135.5 78.5 66.2

但线条的长度会有所不同。每行前面也有几个空格。 我想使用正则表达式来解析该行并将每个数字放入一个数组中,以便稍后进行操作。

使用

std::getline(is, line);

std::tr1::regex rx("[0-9-\.]+");
std::tr1::cmatch res;
std::tr1::regex_search(line.c_str(), res, rx);

只匹配第一个数字。相反,如果我使用线锚,例如

"^[0-9-\.]+$" 
"^[0-9-\.]+"

我没有匹配到

"[0-9-\.]+$"

只匹配最后一个数字。所以我可能做错了什么。感谢您的帮助。

【问题讨论】:

  • res 是一个数组,即 res[1], res[2], res[3]... 应该有你的匹配项。你检查过还是刚刚获得资源?
  • regexp 在这里确实不是最好的解决方案,只是在浮点数中使用 operator>> 更容易使用,也更适合。
  • 我同意 PlasmaHH,但谁知道出于什么原因,有人想玩正则表达式...
  • 我检查了 res 的大小,它只包含一个元素。我会使用运算符>>,但每行的元素数量会发生变化,有些行有 15 个,其他行少了。
  • 当然,但这是因为您的正则表达式不正确。 >> 无疑是 C++ 的实现方式,但正则表达式提供了额外的灵活性。很高兴知道。

标签: c++ regex


【解决方案1】:

您的正则表达式可能不正确,您应该尝试:

[0-9\.]+

还请记住,std::tr1::cmatch 返回匹配数组,即res[2] 包含72.7

使用 egrep 你可以做一些实验:

egrep "[0-9-\.]+" /tmp/x
egrep: Invalid range end

但是

egrep "^[0-9\.]+" /tmp/x

仅匹配

129.3 

egrep "[0-9\.]+" /tmp/x

匹配所有

129.3 72.7 121.6 173.6 203.3 120.7 40.5 79.2 94.0 123.2 165.8 178.8 135.5 78.5 66.2

前面不需要^,因为它匹配字符串开头的空字符,即只生成第一个数字序列。

你不需要$,因为它只匹配最后的空字符,因此你只得到最后一个数字序列

你需要+,因为你想得到[0-9\.]类型的所有匹配原子。

您还可以通过发布在任何 unix 系统中获得一个简短的正则表达式匹配指南

man -S 7 regex

附言/tmp/x 是一个文件,其中包含问题中提供的行。

【讨论】:

    【解决方案2】:

    嗯,伪代码

     for str in strtok(input string)
         vector[index] = convert str to float
    

    这是一个使用大量流魔法的示例:Split a string in C++?

    这是一个使用向量的示例: Splitting a string by whitespace in c++

    但是普通的旧 strtok 可能是最简单的: http://www.cplusplus.com/reference/clibrary/cstring/strtok/

    在这种情况下,你会得到类似的东西

    Vector flts = // create it 
    for(int ix=0, char * cp; cp = strtok(str," "); ix++){
        flts[ix] = atof(cp);
    }
    

    现在,这很像 C,因为我没有练习 C++,但这里的关键点是,尝试使用正则表达式会使它变得过于复杂。

    【讨论】:

    • 确实...当您必须在标准兼容和线程安全之间进行选择时,strtok 胜出!
    • 感谢您的帮助。生病试一试。是的,对于这样一个简单的任务,正则表达式有点矫枉过正,但这是我首先想到的。我有点习惯使用 c++。
    • 天啊,@g24l,你认为这就是我说“这很像 C”的原因吗? Btu 如果我真的以 C 方式进行操作,我会使用 sscanf
    • 我见过,但这是关于 C++ 的问题中公认的答案,可能有点误导。
    【解决方案3】:

    我看起来正则表达式有一个小问题:

    "[0-9-\.]+"
    

    应该更像:

     "[0-9\.]"
    

    【讨论】:

      【解决方案4】:

      您需要在匹配中的数字之间包含空格以匹配整行。

      顺便说一句,请查看C++ tokenize a string using a regular expression 以查看与之密切相关的答案。

      您真的不应该在这里使用数组,使用标准容器是为了以后必须查看此代码的任何人的安全、方便和理智。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多