regex.h 匹配 OSX 和 Linux 之间的差异
regex.h matching differences between OSX and 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 工作区,请参阅 this link。但是我发现,当我尝试使用 regex.h
进行匹配时,它在 OSX 或 linux 上的表现有所不同,特别是:
失败于:
OSX:10.14.6
LLVM: 10.0.1 (clang-1001.0.46.4)
致力于:
linux: Ubuntu 18.04
g++: 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(®ex,matchfile.c_str(),REG_EXTENDED);
regerror(reti, ®ex, 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(®ex,iline.c_str(),6,input_matchptr,0);
regerror(reti, ®ex, buffer, 100);
if(reti==0)
printf("regex compile success!\n");
else
printf("regexec() failed with '%s'\n", buffer);
//******************************************
return 0;
我还修改了我的正则表达式以符合 POSIX(我认为?),根据 this post 删除了之前使用的 +?
和 *?
运算符,但是可能遗漏了一些让我与 POSIX 不兼容的东西?但是,正则表达式现在似乎可以正确编译,这让我觉得我使用了有效的正则表达式,但我仍然不明白为什么没有获得匹配项。据我所知,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 字符 class,而不是类似 Perl 的 \s
。
您提到您尝试 [:space:]
括号表达式之外,但它没有工作 - 这是预期的。根据 Character Classes、
[:digit:]
is a POSIX character class, used inside a bracket expression like [x-z[:digit:]]
.
这意味着 POSIX 字符 classes 仅在括号表达式内使用时按原样解析。
我需要将以下行与多个捕获组匹配:
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 工作区,请参阅 this link。但是我发现,当我尝试使用 regex.h
进行匹配时,它在 OSX 或 linux 上的表现有所不同,特别是:
失败于: OSX:10.14.6 LLVM: 10.0.1 (clang-1001.0.46.4)
致力于: linux: Ubuntu 18.04 g++: 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(®ex,matchfile.c_str(),REG_EXTENDED);
regerror(reti, ®ex, 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(®ex,iline.c_str(),6,input_matchptr,0);
regerror(reti, ®ex, buffer, 100);
if(reti==0)
printf("regex compile success!\n");
else
printf("regexec() failed with '%s'\n", buffer);
//******************************************
return 0;
我还修改了我的正则表达式以符合 POSIX(我认为?),根据 this post 删除了之前使用的 +?
和 *?
运算符,但是可能遗漏了一些让我与 POSIX 不兼容的东西?但是,正则表达式现在似乎可以正确编译,这让我觉得我使用了有效的正则表达式,但我仍然不明白为什么没有获得匹配项。据我所知,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 字符 class,而不是类似 Perl 的 \s
。
您提到您尝试 [:space:]
括号表达式之外,但它没有工作 - 这是预期的。根据 Character Classes、
[:digit:]
is a POSIX character class, used inside a bracket expression like[x-z[:digit:]]
.
这意味着 POSIX 字符 classes 仅在括号表达式内使用时按原样解析。