Ruby正则表达式匹配<ul>标记之间的内容</ul>

时间:2014-08-19 19:58:57

标签: html ruby regex

我有一个脚本来抓取页面并进行编辑。页面HTML看起来像这样:

<p>Title</p>...extra content...<ul><li>Item1</li><li>Item2</li></ul>

有多个标题和多个无序列表,但我想用正则表达式更改每个列表,该表达式可以找到具有特定标题的列表,并在Ruby中使用.sub来替换它。

我目前的正则表达式如下:

regex = /<p>Title1?.*<\/ul>/

现在,如果正则表达式下面有任何项目,它将与最后一个标记匹配,并意外地抓住它下面的所有列表,例如,如果我有这个内容:

content = "<p>Title1</p><ul><li>Item1</li><li>Item2</li></ul><p>Title2</p><ul><li>Item1</li><li>Item2</li><li>Item3</li></ul>"

我想在标题1的部分添加另一个列表项:

content.sub(regex, "<p>Title1</p><ul><li>Item1</li><li>Item2</li><li>NEW_ITEM</li></ul>)

它会删除它下面的所有项目。如何重写我的正则表达式以仅选择要替换的第一个/ ul标记?

3 个答案:

答案 0 :(得分:4)

“我想用正则表达式更改每个列表。”不,你没有。你真的不想走这条路,因为它充满痛苦,悲伤和泪水。有一天,有人会在列表项中放置一个列表项。

Nokogiri这样的库使得操作HTML非常容易。没有理由不使用类似的东西:

require 'nokogiri'

html = "<p>Title</p>...extra content...<ul><li>Item1</li><li>Item2</li></ul>"

doc = Nokogiri::HTML(html)

doc.css('ul').children.first.inner_html = 'Replaced Text'

puts doc.to_s

这是“替换第一个列表项中的文本”的简单示例。它可以很容易地适应其他事情,因为css方法采用一个简单的CSS选择器,与jQuery不同。

答案 1 :(得分:1)

使用非贪婪(懒惰)量词.*?

请参阅Ruby Regexp repetition的此解释。

regex = /<p>Title1?.*?<\/ul>/

答案 2 :(得分:1)

  

...它使用换行符重新格式化html并将所有<br />更改为<br> ...

这通常是因为在将文档发布为HTML或XHTML时使用了错误的方法:

doc = Nokogiri::HTML::DocumentFragment.parse('<p>foo<br />bar</p>')
doc.to_xhtml # => "<p>foo<br />bar</p>"
doc.to_html # => "<p>foo<br>bar</p>"

doc = Nokogiri::HTML::DocumentFragment.parse('<p>foo<br>bar</p>')
doc.to_xhtml # => "<p>foo<br />bar</p>"
doc.to_html # => "<p>foo<br>bar</p>"

至于他们以前虚假地添加线端,我还没有看到。如果您正在修改DOM,告诉 Nokogiri可以做到这一点,但是从我所看到的,它自己的Nokogiri非常温和。