【问题标题】:Ignore img tags in preg_replace忽略 preg_replace 中的 img 标签
【发布时间】:2015-04-11 16:10:14
【问题描述】:

我想替换 H​​TML 字符串中的一个词,但如果该词在 'img' 元素的属性中,我想排除替换。

例子:

$word = 'google';
$html = 'I like google and here is its logo <img src="images/google.png" alt="Image of google logo" />';

$replacement = '<a href="http://google.com">Google</a>';
$result =  preg_replace('/\s'.($word).'/u', $replacement, $html);

preg_replace 还将替换 'src' 和 'alt' 属性中的“google”单词,我希望它只替换 'img' 元素之外的单词。

【问题讨论】:

  • 您所要求的不可能以可靠的方式完成。正则表达式是一个很棒的工具,但并非适用于所有任务。您想为此类任务使用 DOM 解析器。
  • @arkascha 似乎可以使用正则表达式! stackoverflow.com/a/29580308/3933332
  • @Rizier123 我从来没有声称这是不可能的,是吗?这种方法的问题是你永远不会得到一个可靠的解决方案。您总是会发现更多情况下它无法按预期工作并且您必须一次又一次地修复它。
  • @arkascha 你能提供一个简单的代码来使用 DOM 解析器吗?

标签: php regex html-parsing preg-replace


【解决方案1】:

您可以使用丢弃模式。例如,您可以使用这样的正则表达式:

<.*?google.*?\/>(*SKIP)(*FAIL)|google

Working demo

这种模式背后的想法是丢弃 &lt;&gt; 中的 google 单词,但保留其余部分:

<.*?google.*?\/>(*SKIP)(*FAIL)  --> This part will skip the matches where google is within <...>
|google                         --> but will keep the others google

您可以添加许多您想要的“丢弃”模式,例如:

discard patt1(*SKIP)(*FAIL)|discard patt(*SKIP)(*FAIL)|...(*SKIP)(*FAIL)|keep this

【讨论】:

  • 谢谢@Fede 我可以忽略“img”和“a”元素吗?
  • @WaseemAbuSenjer 是的,你可以使用这个正则表达式 &lt;(img|a).*?google.*?\/&gt;(*SKIP)(*F)|google regex101.com/r/oM3qQ4/2
【解决方案2】:

使用积极的前瞻(?=.*?&lt;.*?/&gt;)

$html = 'I like google and here is its logo <img src="images/google.png" alt="Image of google logo" />';

$result = preg_replace('%(?=.*?<.*?/>)google%im', 'ANOTHER WORD', $html);

DEMO

解释

(?=.*?<.*?/>)google
-------------------

Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=.*?<.*?/>)»
   Match any single character that is NOT a line break character (line feed) «.*?»
      Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
   Match the character “<” literally «<»
   Match any single character that is NOT a line break character (line feed) «.*?»
      Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
   Match the character string “/>” literally «/>»
Match the character string “google” literally (case insensitive) «google»

ANOTHER WORD

Insert the character string “ANOTHER WORD” literally «ANOTHER WORD»

更多关于Regex Lookaround的信息

【讨论】:

    猜你喜欢
    • 2012-01-01
    • 1970-01-01
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    相关资源
    最近更新 更多