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(&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(我认为?),根据 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 仅在括号表达式内使用时按原样解析。