0

是否有可能以及如何仅选择未被锚标签包围的<a></a>标签?
我不可能改变整个系统来使用类似的东西,DOMDocument所以我被正则表达式困住了。已经搜索了一段时间,但似乎无法(或不知道如何)找到我需要的答案。

我目前正在使用简单的正则表达式,它将选择我想选择的所有标签,但我必须排除一些被锚点包围的标签,并且不知道如何解决这个问题。任何帮助表示赞赏。

样本数据

Suspendisse potenti. Nam pellentesque eu lectus eget convallis. 
Curabitur <span>porta metus sem</span>, nec fermentum urna elementum ac. 
Praesent et ultrices urna. <span>Curabitur id nisl</span> in sapien ultrices laoreet vel et quam.
Cras nisi felis, vestibulum id adipiscing venenatis, dignissim vel tortor. 
<a><span>Integer sapien dolor</span></a>, pellentesque sed ultricies in, ornare eu felis. 
Cras volutpat hendrerit odio id aliquet. 

在此,我将选择所有<span>带有类似内容的标签,'/<span>(.*?)<\/span>/'但这会选择所有跨度,因为我需要未包含在<a></a>.

只要能完成工作,多步骤过程就可以了,这意味着不需要用一个表达式选择所有内容。

4

3 回答 3

0

使用否定的向后看:

(?<!<a>)<span>(.*?)<\/span>

这将排除-tag 开头<span>的 -tags 。<a>

为了完整起见,如果您只需要匹配一个完整的环境,那么添加一个负前瞻:

(?<!<a>)<span>(.*?)<\/span>(?!</a>)

查看演示:http ://regexr.com?374pp

于 2013-11-11T08:18:54.243 回答
0
(?<!<a.*?>)(<(?!a\b)(.*?\b).*?>.*</\2>|<(?!a\b).*?\b />)(?!</a>)

正则表达式可视化

调试演示

这应该匹配每个没有被 a-Tags 包围的 HTML 标签

如果您只需要一个跨标签匹配器,请使用这个:

(?<!<a.*?>)<span.*?>.*</span>(?!</a>)

正则表达式可视化

调试演示

如果您需要有关正则表达式环视断言的更多信息:http ://www.regular-expressions.info/lookaround.html

于 2013-11-11T08:26:12.090 回答
0

干得好:

preg_match_all(
  '%\G(?:[^<]+|<a\b[^>]*>.*?</a>|<(?!span\b)[^>]*>)*\K<span[^>]*>.*?</span>%s',
  $subject, $result);

确定不能使用 HTML 解析器吗?:D

为了解释它,我首先将它放在一个更易读的格式中。

\G                        # (1)
(?:
    [^<]+                 # (2)
  |
    <a\b[^>]*>.*?</a>     # (3)
  |
    <(?!span\b)[^>]*>     # (4)
)*
\K                        # (5)
<span[^>]*>.*?</span>

以下是它的工作原理:

  1. \G强制每场连续比赛从前一场比赛结束的位置开始。

  2. 任何不是标签开头的东西

  3. 一个完整的<a>元素(假设它们从不包含其他<a>元素)

  4. 任何其他标签,除了<span>

  5. \K重置匹配开始位置,因此到目前为止匹配的所有内容都不会被视为匹配的一部分。它实际上是一个积极的向后看,并不关心它匹配了多少个字符。

通常的免责声明适用。即使在完全有效的 HTML 中,这个正则表达式也有很多可能会失败。例如,它假定左尖括号 ( <) 总是标记标签的开始,而实际上它可以在许多其他地方找到。

于 2013-11-11T10:42:06.550 回答