为什么我的正则表达式不匹配?

时间:2012-11-29 15:18:36

标签: php regex html-parsing

我有一个这样的字符串:

<li class="level0 nav-2 last level-top parent">
   <a href="#" class="level-top"><span>XYZ</span></a>
   <ul class="level0">
      <li class="level1 nav-2-1 first"><a href="#"><span>Farben</span></a></li>
      <li class="level1 nav-2-2 last"><a href="#"><span>Muster</span></a></li>
   </ul>
</li>

现在我想匹配最后一个li,但只有在字符串中的某个位置它才是XYZ。我试过了

/<li class="level1 nav-(\d+)-(\d+) last">.+(<\/li>)/

哪个找到最后一个li,但是我无法弄清楚如果它后跟XYZ只能添加它。我试过了

/.*XYZ.*<li class="level1 nav-(\d+)-(\d+) last">.+(<\/li>)/

但这没效果。

想法?谢谢:))

4 个答案:

答案 0 :(得分:2)

如果你想使用REGEX:

XYZ(.*\n( |\t)*.*)*<li class="level1 nav-(\d+)-(\d+) last">.+(<\/li>)

你需要精确&#34; level1导航 - (\ d +) - (\ d +)&#34; ?

您稍后需要使用什么?

也许你可以抓住所需的部分:

XYZ(.*\n( |\t)*.*)*<li class=".*last">(.+)<\/li>

答案 1 :(得分:0)

尝试使用正则表达式:

/XYZ(?s:.*)<li class="level1 nav-(\d+)-(\d+) last">.+(<\/li>)/

子模式中的s修饰符允许.匹配换行符。

答案 2 :(得分:0)

使用phpQuery,这是jQuery的php端口

,你可以很容易地做到这一点

然后使用例如

$liElm = pq("ul li:last:contains('xyz')");

请注意,phpQuery不如正则表达式快,但更容易处理,更舒适。

答案 3 :(得分:0)

你就是这样做的。

我想指出,就像我一直使用Markup解析一样,DOM导航工具最适合于良好形成的标记。您可以使用HTML Parsers将其转换为XML文档并使用XPath或许多其他选项。有时,使用非良好格式的HTML或其他文档类型,这是过度的甚至是不可能的。话虽如此,您的请求(在我看来)转换为:

匹配ListItem HTML对象&lt; li ...&lt; / li后面跟着另一个ListItem这样,最后一个,但要求它前面跟着字符串“xyz”

(?is)(?<=xyz.*?)<li\s(?!.*?<li).*?</li>

此正则表达式使用Case Insensitive和SingleLine选项,要求在匹配之前存在“xyz”和其他任何内容,找到ListItem后面没有其他ListItem,并获取整个ListItem。不需要CaptureGroup,因为Lookahead和Lookbehind是零宽度断言并且不捕获。所以这是整个比赛的Capture Group 0。

马里奥建议的贪婪,这对小块来说很好,但是对于大型文件来说,这需要大量的回溯。

(?is)xyz.*(<li.*?</li>)

此正则表达式要求您使用捕获组,因为匹配是贪婪的。并不是说捕获组是坏的,只是更多的代码。