通过REGEX删除CSS注释时出错

Chr*_*kas 5 php regex php-7.3

证明这两个序列(以前都有效)

"`([\n\A;]+)\/\*(.+?)\*\/`ism" => "$1",     // error
"`([\n\A;\s]+)//(.+?)[\n\r]`ism" =>"$1\n",  // error
Run Code Online (Sandbox Code Playgroud)

现在在PHP 7.3中引发错误

警告:preg_replace():编译失败:转义序列在字符类偏移量4中无效

语境:考虑一下这个技巧,它可以从字符串中删除CSS注释

$buffer = ".selector {color:#fff; } /* some comment to remove*/";
$regex = array(
"`^([\t\s]+)`ism"=>'',
"`^\/\*(.+?)\*\/`ism"=>"",
"`([\n\A;]+)\/\*(.+?)\*\/`ism"=>"$1",     // 7.3 error
"`([\n\A;\s]+)//(.+?)[\n\r]`ism"=>"$1\n", // 7.3 error
"`(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+`ism"=>"\n"
);
$buffer = preg_replace(array_keys($regex),$regex,$buffer);
//returns cleaned up $buffer value with pure css and no comments
Run Code Online (Sandbox Code Playgroud)

请参阅:https//stackoverflow.com/a/1581063/1293658

Q1 -任何想法什么是错,在这种情况下,正则表达式?该线程似乎表明它只是放错了反斜杠 https://github.com/thujohn/twitter/issues/250

Q2 -这是一个PHP 7.3的错误或与此代码正则表达式序列的问题?

Wik*_*żew 3

不要在字符类中使用零宽度断言

  • ^, $, \A, \b, \B, \Z, \z, \G-作为锚点、(非)单词边界- 在字符类中没有意义,因为它们不匹配任何字符。和在字符类中的含义有所不同:如果在 open 之后使用,则为否定字符类标记^,或者表示文字。表示退格字符。\b^[^\b

  • 你也不能\R在那里使用(=任何换行符)。

字符类内部的两个模式必须使用交替运算符\A重写为分组构造, :(...)|

"`(\A|[\n;]+)/\*.+?\*/`s"=>"$1", 
"`(\A|[;\s]+)//.+\R`"=>"$1\n", 
Run Code Online (Sandbox Code Playgroud)

我删除了您不使用的冗余修饰符和捕获组,并替换[\r\n]\R. 还可以"`(\A|[\n;]+)/\*.+?\*/`s"=>"$1" 以更有效的方式重写

"`(\A|[\n;]+)/\*[^*]*\*+(?:[^/*][^*]*\*+)*/`"=>"$1"
Run Code Online (Sandbox Code Playgroud)

请注意,在 PHP 7.3 中,acc。在捆绑的 PCRE 库表的升级历史记录中,正则表达式库是 PCRE 10.32。请参阅PCRE 到 PCRE2 的迁移

在 PHP 7.2 之前,PHP 使用旧 PCRE 库的 8.x 版本,从 PHP 7.3 开始,PHP 将使用 PCRE2。请注意,PCRE2 被认为是一个新库,尽管它基于 PCRE (8.x) 并在很大程度上与之兼容。

附件。对于此资源,更新后的库对正则表达式模式更加严格,并且现在将以前宽松接受的用户错误视为真正的错误:

  • 修改器 S 现在默认处于启用状态。PCRE 做了一些额外的优化。
  • 默认情况下禁用选项 X。它使得 PCRE 比以前做更多的语法验证。
  • 使用的是 Unicode 10,而它是 Unicode 7。这意味着更多的表情符号、更多的字符和更多的集合。Unicode 正则表达式可能会受到影响。
  • 一些无效模式可能会受到影响。

简单来说,PCRE2 在模式验证方面更加严格,因此升级后,您现有的一些模式将无法再编译。