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

时间:2016-05-10 11:48:27

标签: php regex preg-replace preg-match pcre

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

我几乎找不到任何在线文档,所以我转向Jeffrey E.F. Friedl's Mastering Regular Expressions

我看到它的方式,/(?(?<=NUM:)\d+|\w+)/之类的内容应该与前面有NUM:的数字相匹配,否则它应匹配一个单词。

但是出于一些奇怪的原因,它总是返回true,匹配数据对我来说也没有意义。有人可以向我解释发生了什么事吗?

我想做的是:

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

在行动中,我需要的输入输出序列是:

  1. 输入:创建一件白衬衫。
  2. 输出制作一件白衬衫。

    1. 输入:“创建一件白衬衫。”
    2. 输出“创造一件白衬衫”

      1. 输入:你好,创建一些好的代码。
      2. 输出:你好,做一些好的代码。

        1. 输入:“你好”“制作一些”好“代码。”
        2. 输出:“你好”“制作一些”好“的代码。”

          谢谢大家!

          修改:我想做类似的事情:如果有开场报价,请确保在匹配关键字create之前有一个结束对。希望这是有道理的,也是可能的。

1 个答案:

答案 0 :(得分:1)

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

使用与引用的子字符串匹配的替代分支并使用(*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组(稍后可以用替换模式中的$1引用) - 双引号字符串
  • | - 或
  • creat(?:e|ing) - 匹配createcreating

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