【问题标题】:Conditional regex in PHP doesn't seem to workPHP中的条件正则表达式似乎不起作用
【发布时间】:2016-05-10 11:48:26
【问题描述】:

执行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. 输入:制作一件白衬衫。

输出:做一件白衬衫。

  1. 输入:“制作一件白衬衫。”

输出:“创建一件白衬衫”

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

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

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

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

谢谢大家!

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

【问题讨论】:

  • 那么,您使用的正则表达式是什么?仅限creat(?:e|ing)?但它在任何地方都匹配create
  • 我什至无法开始,因为 if-else 给了我意想不到的结果。

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


【解决方案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 字符串与转义序列匹配,则应至少使用 "[^"\\\\]*(?:\\\\.[^"\\\\]*)*"(在代码中)。

【讨论】:

  • Wiktor,这两个表达式都给了我相同的结果。 'create',内部和外部引号都被 'make' 替换,而不是所需的输出,其中 'create' 仅在引号外部替换。
  • 您查看了演示吗? We create it, "they create that" -> We make it, "they create that"
  • 我做到了。我直接从那里复制了代码和输入,并在我的本地主机上运行它。它取代了“创造”两个词。我正在通过 textarea 获取输入并将其也输出到浏览器上,希望这不会产生影响。
  • 你确定你有"吗?不是" 或任何其他literal“实体”?检查您之前是否有htmlentitieshtmlentities 在运行正则表达式之前不能使用。
  • 这正是发生的事情,很久以前就写了代码。刚刚添加了 htmlspecialchars_decode($input) 并像魅力一样工作。第二个例子很有道理,也很聪明,你自己想出来的吗?第一个虽然看起来很陌生,你能告诉我它是如何工作的吗?
猜你喜欢
  • 1970-01-01
  • 2016-01-31
  • 1970-01-01
  • 2019-04-05
  • 1970-01-01
  • 1970-01-01
  • 2019-01-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多