使用c ++ regex验证ASCII GnuPlot文件

时间:2015-04-07 10:51:59

标签: c++ regex validation

我一直在努力做到这一点,但似乎无法让事情按照我想要的方式发挥作用。

我有一个包含数百万行浮点值的ASCII文件,用空格分隔。使用std::istream_iterator<double>读取这些值非常简单,但我想提前验证文件,以确保它按照我描述的方式进行格式化。由于只有一种正确的格式,以及如何形成错误的方式,我想用std::regex来解决这个问题。

这就是我提出的:

std::string begln( "^" );
std::string endln( "$" );
std::string fp( "[-+]?[0-9]*.?[0-9]+([eE][-+]?[0-9]+)?." );
std::string space( "[[:space:]]{1}" );
std::regex regexp( "(" + begln + fp + space + fp + space + fp + endln + ")+" );

我想表达的是:一行由行的开头和结尾之间的东西组成,它包含三组浮点值,用一个空格分隔,我正在寻找这些行中的一行或多行

我希望有效的数据文件只有一个没有前缀和后缀的匹配。

但是,嘿,因为这些值将进入std::vector<std::array<double, 3>>,为什么我不重用正则表达式机制并从匹配列表中获取值?如果文件有效,那么绝对琐碎的正则表达式只能匹配单独的行,并构造一个std::sregex_iterator来迭代这些行。在这一点上,无论是再次使用正则表达式还是使用std::string,如何从一行std::stringsteam获取值,这只是一个痴迷的问题。

1 个答案:

答案 0 :(得分:0)

为什么不呢?你不会想要这个的原因是因为正则表达式是绝对矫枉过正的。它们可以匹配更复杂的语法,并且能够在运行时读取这些语法。这种灵活性的价格很高。必须包含所有可能的解析器。没有当前的编译器足够聪明,你可以看到你只使用[[:space:]]作为正则表达式。 (事实上​​,没有C ++编译器或链接器知道有关正则表达式的任何信息 - 这纯粹是一个库事物。)

相比之下,operator>>被重载,编译器会确切地看到您在编译时使用了哪些重载。链接器被告知这一点,并且仅包含相关代码。

此外,CPU分支预测器很快就会注意到operator>>几乎总是成功,这是一个进一步的加速。你的正则表达式代码不太可能以同样的方式受益 - [0-9]*中的条件部分至少是一个更深层次的间接层。