相同的正则expression式,但在Linux和Windows上只有C ++不同的结果

我的命令行程序有这个模式:
^s?([/|@#])(?:(?!\1).)+\1(?:(?!\1).)*\1(?:(?:gi?|ig)?(?:\1\d\d?)?|i)?$
基于C ++的ECMAScript 262

这是检查用户是否input了正确命令的特殊模式。 这是一个像这样的stringtesting:
optional-s/one-or-more/anything/optional-g-or-i/optional-2-digits

这是我以前的问题,为什么我需要这种模式 。
虽然它在Linux上正常工作,但在Windows上不起作用。 另外我知道两台机器上的换行符,我已经读过这个: 在Linux和Windows上如何处理\ n和\ r?

我的程序可以处理任何文件,它只获取命令行argv[ 1 ]的第一个参数,而std::regex_matchtestinginput的用户概要是否正确。
就像: ./program 's/one/two/' *.txt ,对于所有的txt文件

C ++代码:

 std::string argv_1 = argv[ 1 ]; // => s/one/two/ bool rename_is_correct = std::regex_match( argv_1, std::basic_regex< char > ( "s?([/|@#])(?:(?!\\1).)+\\1(?:(?!\\1).)*\\1(?:(?:gi?|ig)?(?:\\1-?[1-9]\\d?)?|i)?" ) ); 

问题:
虽然模式不贪心 , 在Windows上,它变得贪婪,并匹配更多的4个分隔符。 因此它不应该匹配/one/two/three/four/five/而是这个string匹配!


注意:

  • 我故意放弃^$断言,因为在C ++正则expression式默认情况下std::regex_match有它们,它不需要使用它们
  • 另外两个反斜杠\\ ; 其中之一就是逃避angular色
  • javescript代码说不
 const regex = /^s?([/|@#])(?:(?!\1).)+\1(?:(?!\1).)*\1((?:gi?|gi)\1-?[1-9]\d|i)?$/gm; var str = 's/one/two/gi/-33/'; if( str.match( regex ) ){ console.log( "okay" ); } else { console.log( "no" ); } 

  • Perl也说不,正如你可以在屏幕截图中看到的,但是c ++表示okay

在这里输入图像说明

有人知道为什么它变得贪婪?

谢谢。

GCC中的一个错误似乎在5.4版本中得到了修复。 我的猜测是你正在Windows设置上运行一个较旧的版本。

看到在输出的差异:

  • 版本4.9 :“okey”(错误)
  • 版本5.4 :“否”(右)

是否包括boost似乎没有区别。

这个bug与(?!\\1) ,用(?![/]) (在两个实例中)代替它解决了这个问题,但显然这会限制正则表达式仅用于/ delimiter:

  • 版本4.9 (?![1]) :“否”(正确)

此外,这个错误出现在这个简单的正则表达式中: (.)((?!\\1).)应该拒绝一个像aa这样的输入:

  • 版本5.4 :“否”(右)
  • 版本4.9 :“okey”(错误)

结论:确保安装GCC版本5.4或更高版本。