关于正则表达式:c ++正则表达式匹配整行

c++ regular expression matching whole line

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

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

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

使用

1
2
3
4
5
std::getline(is, line);

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

只匹配第一个号码。如果改为使用线锚,例如

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

我没有火柴,而且

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

只匹配最后一个号码。所以我可能做错了什么。谢谢你的帮助。


伪码

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

下面是一个使用大量流魔法的例子:在C++中分割一个字符串?

下面是一个使用向量的例子:在C++中用空格分割字符串

但普通的老斯特托克可能是最简单的:网址:http://www.cplusplus.com/reference/clibrary/cstring/strtoktok/

在这种情况下,你会得到

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

这是非常类似C的,因为我没有练习C++,但是这里的重点是通过使用正则表达式,使它变得过于复杂。


您的regex可能不正确,您应该尝试:

1
[0-9\.]+

还请记住,STD::Tr1::CMatRead返回一个匹配数组,即EDCOX1 OR 0包含EDCOX1(1)。

使用egrep,您可以尝试一下:

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

但是

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

火柴只

1
129.3

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

匹配所有

1
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系统中获得一个简短的指南regex匹配

1
man -S 7 regex

P.S./tmp/x是一个带有问题中提供的行的文件。


我觉得Regex有一个小问题:

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

应该更像:

1
"[0-9\.]"

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

顺便说一下,看看C++使用正则表达式标记字符串,以查看一个非常密切相关的答案。

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