PHP 中的条件正则表达式似乎不起作用

Conditional regex in PHP doesn't seem to work

执行 regular expression match in PHP using the preg suite,我知道您可以在正则表达式中表示条件语句。

我在网上几乎找不到任何文档,所以我求助于 Jeffrey E.F. Friedl's Mastering Regular Expressions

在我看来,像 /(?(?<=NUM:)\d+|\w+)/ 这样的东西在它前面有 NUM: 时应该匹配一个数字,否则它应该匹配一个单词。

但由于某些奇怪的原因,它总是 returns 正确,匹配数据对我来说也没有意义。谁能给我解释一下这是怎么回事?

我想做的是:

preg_replace('/creat(?:e|ing)/i', 'make', $input)
but only when '/creat(?:e|ing)/i' is not surrounded by quotes.

实际上,我需要的输入输出序列是:

  1. 输入:创建一件白衬衫。

输出:做一件白衬衫。

  1. 输入: "create a white shirt."

输出: "create a white shirt"

  1. 输入:你好创造一些好的代码。

输出:你好写一些好的代码。

  1. 输入:"hello""make some"好"code."

输出:"hello""make some"好"code."

谢谢大家!

编辑:我想做这样的事情:如果有一个开引号,在这种情况下,确保它在匹配关键字 create 之前有一个结束对.希望这是有道理的并且是可能的。

您不需要任何条件结构来跳过引号内的内容。有两种方法。

使用替代分支匹配带引号的子字符串并使用 (*SKIP)(*FAIL) 动词:

 preg_replace('/"[^"]*"(*SKIP)(*F)|creat(?:e|ing)/i', 'make', $input)

图案详情:

  • "[^"]*" - 匹配 ",然后是 " 以外的 0+ 个字符,然后是 "
  • (*SKIP)(*F) - 使正则表达式引擎丢弃当前匹配的文本并从当前索引
  • 开始
  • | - 或...
  • creat(?:e|ing) - 匹配 createcreating.

demo

另一种方法是仅使用捕获并使用 preg_replace_callback,您可以在其中检查组是否匹配(并适当地建立替换逻辑):

 preg_replace_callback('/("[^"]*")|creat(?:e|ing)/i', function($m) {
     return !empty($m[1]) ? $m[1] : 'make';
 }, $input)

IDEONE demo

图案详情:

  • ("[^"]*") - 第 1 组(稍后可以从替换模式中用 </code> 引用) - 双引号字符串 </li> <li><code>| - 或
  • creat(?:e|ing) - 匹配 createcreating.

请注意,"[^"]*" 是一个示例正则表达式,如果您需要将 C 字符串与转义序列匹配,您应该至少使用 "[^"\\]*(?:\\.[^"\\]*)*"(在代码中)。