regex.h匹配OSX和Linux之间的差异



我需要将以下行与多个捕获组匹配:

0.625846        29Si    29      [4934.39        0]      [0.84   100000000000000.0]

我使用正则表达式:

^(0+.[0-9]?e?[+-]?[0-9]+)s+([0-9]+.?[0-9]*|[0-9][0-9]?[0-9]?[A-Z][a-z]?)s+([0-9][0-9]?[0-9]?)s+([.*])s+([.*])$

有关regex101工作区,请参阅此链接。然而,我发现当我使用regex.h尝试匹配时,它在OSX或linux上的表现不同,特别是:

失败时间:OSX:10.14.6LLVM:10.0.1(clang-1001.0.46.4(

工作范围:linux:Ubuntu 18.04g++:7.5.0

我编写了一个简短的代码来重现这个问题,用g++ regex.cpp -o regex:编译

#include <iostream>
//regex
#include <regex.h>
using namespace std;
int main(int argc, char** argv) {

//define a buffer for keeping results of regex matching 
char       buffer[100];
//regex object to use
regex_t regex;
//*****regex match and input file line*******
string iline = "0.625846        29Si    29      [4934.39        0]      [0.84   100000000000000.0]";
string matchfile="^(0+\.[0-9]?e?[+-]?[0-9]+)\s+([0-9]+\.?[0-9]*|[0-9][0-9]?[0-9]?[A-Z][a-z]?)\s+([0-9][0-9]?[0-9]?)\s+(\[.*\])\s+(\[.*\])$";

//compile the regex 
int reti = regcomp(&regex,matchfile.c_str(),REG_EXTENDED);
regerror(reti, &regex, buffer, 100);
if(reti==0)
printf("regex compile success!n");
else
printf("regcomp() failed with '%s'n", buffer);

//match the input line
regmatch_t input_matchptr[6];
reti = regexec(&regex,iline.c_str(),6,input_matchptr,0);
regerror(reti, &regex, buffer, 100);
if(reti==0)
printf("regex compile success!n");
else
printf("regexec() failed with '%s'n", buffer);
//******************************************
return 0;

我还修改了我的正则表达式以符合POSIX(我想是?(,根据这篇文章,我删除了以前使用的+?*?运算符,但可能遗漏了一些使我与POSIX不兼容的内容?然而,regex现在似乎编译正确,这让我觉得我使用了一个有效的regex,但我仍然不明白为什么没有获得匹配。我理解LLVM的要求。

如何修改正则表达式以正确匹配?

要回答直接的问题,您需要使用

string matchfile="^(0+\.[0-9]?e?[+-]?[0-9]+)[[:space:]]+([0-9]+\.?[0-9]*|[0-9][0-9]?[0-9]?[A-Z][a-z]?)[[:space:]]+([0-9][0-9]?[0-9]?)[[:space:]]+(\[.*\])[[:space:]]+(\[.*\])$";

也就是说,您可以在括号表达式中使用[:space:]POSIX字符类,而不是像s那样使用Perl。

您提到您在括号表达式之外尝试了[:space:],但它不起作用——这是意料之中的事。根据字符类

[:digit:]是一个POSIX字符类,在类似[x-z[:digit:]]的括号表达式中使用。

这意味着POSIX字符类只有在括号表达式中使用时才被解析为这样。

最新更新