1

我有一个这样的字符串:

<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

4 回答 4

2

如果你想使用 REGEX :

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

你需要精确的 "level1 nav-(\d+)-(\d+)" 吗?

你以后需要用什么?

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

XYZ(.*\n( |\t)*.*)*<li class=".*last">(.+)<\/li>
于 2012-11-29T15:51:12.550 回答
0

尝试使用正则表达式:

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

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

于 2012-11-29T15:40:25.647 回答
0

这就是你的做法。

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

匹配未跟随另一个 ListItem 的 ListItem HTML 对象 <li...</li 因此,最后一个,但要求它前面有字符串“xyz”

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

此 Regex 使用不区分大小写和 SingleLine 选项,要求匹配之前存在“xyz”和其他任何内容,找到一个 ListItem 后面没有另一个 ListItem,并获取整个 ListItem。不需要 CaptureGroup,因为 Lookahead 和 Lookbehind 是零宽度断言并且不捕获。所以这是整个比赛的捕获组 0。

Mario Suggested Greediness,这对于小块来说很好,但对于大型文档,它需要大量的回溯。

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

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

于 2012-11-29T16:30:54.317 回答
0

您可以使用phpQuery轻松完成此操作,它是 jQuery 的 php 端口

然后使用例如

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

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

于 2012-11-29T15:41:26.007 回答