【问题标题】:regex to skip a tag if it is inside of another tag正则表达式跳过一个标签,如果它在另一个标签内
【发布时间】:2016-10-09 17:16:03
【问题描述】:

如果它不在另一个标签内,我想使用 php 正则表达式从给定字符串中删除锚标签。

输入:

Hi Hello <a href="#">World</a>. This is <div class="some">testing <a href="#">content</a>. some more content</div>

输出:

Hi Hello. This is <div class="some">testing <a href="#">content</a>. some more content</div>

提前致谢。

【问题讨论】:

  • 锚标签在哪里?

标签: php html regex


【解决方案1】:

类似这样的:

$string = 'replace <a href="x">A</a> but not <div> <a>B</a> in tag </div> but also <a>C</a><div></div>';

echo preg_replace('/<a[^>]*?>([^<]*)<\/a>(?![^<]*<\/)/gi', '', $string);

负前瞻确保锚标记后面没有&lt;/
因此它没有被另一个标签包围。

标记的内容在捕获组 1 中,以防您想替换为 '\1' 而不是 ''

如果是关于 div 标签,那么这个会忽略 div 的:

echo preg_replace('/<div.*?>.*?<\/div>\K|<a[^>]*?>([^<]*)<\/a>/gi', '\1', $string);

【讨论】:

  • 只是一个警告,这个正则表达式可能有助于你给出的例子。但是对于更复杂的 html,它也会用多个锚点替换 div 中的一些锚点。
  • 恕我直言需要递归(example) 但正如您所说的一些输入可能很方便。
  • 嗨@LukStorms,我有类似的问题。除了一类之外,如何删除“a”标签?例如.. 'a' 标签如果在类 'tweet'(
    ) 内,则不应删除,否则 'a' 标签将被删除。
  • 也许有负面的回顾。 javascript 不支持,但应该是 php 正则表达式。但是使用起来有点不灵活。例如(?&lt;!&lt;div class="tweet"&gt; )(&lt;a[^&gt;]*?&gt;([^&lt;]*)&lt;\/a&gt;) 将删除所有锚点,无论是否包含。除非它是由字面上的&lt;div class="tweet"&gt; 进行的。 (不是说空间很重要)。 regex101 test.
  • 也可以试试这个(&lt;div class="tweet"&gt;.*?&lt;\/div&gt;)|&lt;a[^&gt;]*?&gt;([^&lt;]*)&lt;\/a&gt; 并将其替换为\1\2。它带有一个 OR。如果它是推文 div,它将进入捕获组一,否则标签的内容将进入捕获组一。 regex101 test
【解决方案2】:

我认为这不是正则表达式的工作,但也尝试使用 common trick(*SKIP)(*FAIL)

'~(<(?!a\b)(\w+)\b(?>(?:(?!</?\2\b).)+(?1)?)*</\2>)(*SKIP)(*F)|<a\b.*?</a>\s*~si'
  • (*SKIP)(*F) 之前的第一部分匹配并跳过 not &lt;a recursively 的任何标签。
  • 管道|之后的第二部分是与末尾可选的whitespace匹配的部分。
  • Flags 已使用:s (PCRE_DOTALL)、i (PCRE_CASELESS)

Try pattern at regex101 或查看eval.in for PHP Demo

使用DOMDocumentother parser 可能有更好的解决方案。

【讨论】:

  • 我第一次看到使用了 *SKIP 和 *FAIL 动词。好的。我将不得不对这些进行一些试验。
猜你喜欢
相关资源
最近更新 更多
热门标签