【问题标题】:error when removing CSS comments via REGEX通过 REGEX 删除 CSS 注释时出错
【发布时间】:2019-09-07 01:16:45
【问题描述】:

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

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

现在在 PHP 7.3 中抛出一个错误

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

CONTEXT:考虑这个片段,它从字符串中删除 CSS cmets

$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

参考:https://stackoverflow.com/a/1581063/1293658

Q1 - 任何想法在这种情况下 REGEX 有什么问题? 该线程似乎表明它只是一个放错位置的反斜杠 https://github.com/thujohn/twitter/issues/250

Q2 -这是 PHP 7.3 的错误还是此代码中的 REGEX 序列有问题?

【问题讨论】:

  • 你想和\A匹配什么?如果您使用 regex101.com 检查您的正则表达式,您会发现它甚至不匹配第一个字符类!正则表达式将与 \w\s 匹配,但我真的不知道这是否是您想要匹配的!
  • 您可能想将正则表达式放在单引号中。避免 PHP Escape 序列解释。
  • 你能提取一个minimal reproducible example吗?此外,如果它适用于 7.2 但适用于 7.3,请查看发行说明。也许代码依赖于已修复的错误。
  • @slepic,使用单引号需要额外的步骤才能在其中获得换行符和回车符。特别是,在这种情况下,仅用单引号替换双引号会更改字符串内容。
  • 如果在模式的开头添加(*NO_JIT)会怎样?

标签: php regex php-7.3


【解决方案1】:

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

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

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

必须将字符类中带有\A 的两个模式重写为分组构造(...),并使用交替运算符|

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

我删除了您不使用的冗余修饰符和捕获组,并将[\r\n] 替换为\R"`(\A|[\n;]+)/\*.+?\*/`s"=>"$1"can also be re-written in a more efficient way

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

请注意,在 PHP 7.3 中,acc.对于Upgrade history of the bundled PCRE library 表,正则表达式库是 PCRE 10.32。见PCRE to PCRE2 migration:

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

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

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

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

【讨论】:

  • 我明白了。所以,这个正则表达式需要仔细重写。我不擅长正则表达式,有什么建议可以去掉 /*CSS cmets*/ 吗?除此之外,我会说您在这里的回答是“技术上正确的”-从我在这里收集的内容来看,“\ A”(我假设是“字符串的开始”)是问题所在。然后我不确定如何在 /*CSS cmets*/ 中定位“\n \r 新行”,如果该段以“新行”开头
  • @ChristianŽagarskas 我在答案中添加了固定模式。
  • 优秀。完美地工作。在玩了几个小时并研究了你在这里写的东西之后,我可以看到我离我认为需要改变的地方还有很长的路要走......谢谢你,我对正则表达式的理解有所增加。干杯。 (我将根据您的其他链接评论订购“掌握正则表达式”的副本。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-10
  • 2015-05-17
  • 1970-01-01
  • 2011-05-11
  • 2015-03-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多