1

我有以下要解析的html:

<h1 class="x">test</h1>
<p>some text <img src="x" /></p>

<h1 class="x1">test2</h1>
<p>some text </p>

<h1 class="2">test3</h1>
<p>some text <img src="x" /></p>

我可以用一个正则表达式将它解析成一个数组吗?

我试过

preg_match_all('#(<h1[^>]*?>)(.*?)(</h1>)(.*)#ism',$html,$arr);

这只给了我一个条目,因为正则表达式的最后一部分是贪婪的,并且

preg_match_all('#(<h1[^>]*?>)(.*?)(</h1>)(.*?)#ism',$html,$arr);

这没有给我任何 之间的 HTML <h1>,因为表达式不是贪婪的。

如何使匹配后的部分变得贪婪,同时匹配尽可能多的事件?

补充评论:

  • 这个问题相当学术,我已经使用 pre_split 解决了这个问题,并且各种其他方法都可以工作,但也可能有缺点(例如 DOM 可能无法在我无法控制的无效 HTML 上工作)。然而,这是一个反复出现的问题,我有兴趣了解更多。
4

2 回答 2

4

你需要某种形式的终端制造商。正则表达式无法猜测到您要匹配的部分。

在这种情况下,可能是(.*?)最后的前瞻断言:

(?=<h1|</body>|\z)#ims
于 2011-03-02T21:59:50.357 回答
1

忽略关于正则表达式不合适的评论,因为它仍然是一个有趣的问题,有两种方法可以解决这个问题:贪婪和懒惰。

该模式的相应部分是:

  • 懒惰.*?(?=<h1|\z)
  • 贪心(?:[^<]+|<(?!h1))*

您可能对贪婪与懒惰的限定符的表现很熟悉,但这里的症结要简单得多。

如果您尝试匹配的字符串完全由 character 组成<,那么惰性和贪婪模式的执行情况大致相同,因为它们都必须检查每个匹配字符的断言。

但是在 HTML 中,其他字符比字符多得多<,因此不需要检查其他字符的贪婪模式可以快几个数量级。

我承认惰性模式更容易阅读,但我认为更好的性能是值得的,并且强烈建议使用x修饰符来评论你的模式。

于 2011-03-02T22:06:35.797 回答