【问题标题】:Are \Q and \E supposed to escape the delimiter in PCRE? [duplicate]\Q 和 \E 是否应该在 PCRE 中转义分隔符? [复制]
【发布时间】:2019-06-21 16:27:37
【问题描述】:

我正在自动生成正则表达式来验证 URL。为了避免冲突,我只是用\Q 和\E 转义常规文本。不幸的是,我发现这种语法在 PHP 中不能正常工作:

reg_match('/\Qfoo/bar\E/', 'foo/bar')
PHP Warning:  preg_match(): Unknown modifier 'b' in ... code on line ...

但它适用于grep:

$ echo 'foo/bar' | grep -P '\Qfoo/bar\E'
foo/bar

在 regex101 中:

https://regex101.com/r/mKI0Q9/1

但不是在 Perl 中:

$ echo 'foo/bar' | perl -ne 'print $_ if m/\Qfoo/bar\E/'
Backslash found where operator expected at -e line 1, near "m/\Qfoo/bar\"

\Q 和 \E 是否应该转义分隔符?

【问题讨论】:

  • 在 PHP 中,分隔符的处理有些粗略beforehand,而不是由知道 \Q 和 \E 的 PCRE 库处理。
  • 只使用[foo/bar]会有什么问题?顺便说一句,无论如何,我看不出用\Q ... \E 包围该文本有什么意义,因为它不包含实际的正则表达式元字符。
  • 你为什么不用preg_quote()?
  • @WiktorStribiżew 这似乎不是一个好的骗局,它没有在源代码中讨论\Q...\E。
  • @Barmar:现在可以(更明确地)。 // 至于 Perl,我相信这更像是一个语言标记器问题(虽然从未研究过)。

标签: php regex perl pcre


【解决方案1】:

PHP documentation 没有明确说明这一点。它说的是:

\Q 和 \E 可用于忽略模式中的正则表达式元字符。例如:\w+\Q.$.\E$ 将匹配一个或多个单词字符,后跟文字 .$. 并锚定在字符串的末尾。

但是,分隔符不是“模式中的元字符”。它们用于确定模式的结束位置。所以操作顺序显然是:

  1. 在输入字符串中查找模式,寻找匹配的分隔符。
  2. 转义模式中\Q 和\E 之间的任何特殊字符。
  3. 执行其余的正则表达式解析。

Perl documentation 更清晰,描述了对引用结构的解析(正则表达式只是其中的一种特殊形式)。

第一步是找到引用结构的结尾....
搜索单字符分隔符时,会跳过转义分隔符和 \....
在此搜索过程中,不注意构造的语义。

和其他地方:

对于正则表达式运算符(qr//、m// 和 s///)的模式,在处理插值之后、处理转义之前应用来自 \Q 的引用。

但这仍然是在它第一次找到正则表达式的结尾之后。

【讨论】:

  • 谢谢,我已经更新了答案以合并其中的一些内容。
猜你喜欢
  • 1970-01-01
  • 2015-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多