Ruby Regex捕获两个字符串之间的所有内容(包括)

时间:2012-11-19 00:15:55

标签: ruby regex string html-sanitizing

我正在尝试清理一些HTML并删除一个标签(我真的想避免使用nokogiri等)。所以我有以下字符串出现我想要摆脱:

<div class="the_class>Some junk here that's different every time</div>

这在我的字符串中只显示一次,我想找到一种方法将其删除。我已经尝试用正则表达式来捕获它,但我找不到一个有效的。

我已尝试过/<div class="the_class">(.*)<\/div>/m这样做有效,但它也会匹配并包含文档中的任何其他</div>标记,这是我不想要的。

有关如何处理此事的任何想法?

2 个答案:

答案 0 :(得分:7)

我相信你正在寻找一个非贪婪的正则表达式,如下所示:

/<div class="the_class">(.*?)<\/div>/m

注意添加的?。现在,捕获组将捕获尽可能少(非贪婪),而不是尽可能多(贪婪)。

答案 1 :(得分:0)

  

因为它增加了另一个依赖项并减慢了我的工作量。使事情变得更复杂。此外,此解决方案不仅适用于HTML标记。我的开始和结束字符串可以是任何东西。

我曾经以相同的方式思考,直到我找到写蜘蛛和网站分析的工作,然后编写一个大的RSS聚合系统 - 解析器是摆脱这种疯狂的唯一途径。没有它,工作永远不会完成。

是的,正则表达式很好用,但有龙等着你。例如,这个常见字符串会导致问题:

'<div class="the_class"><div class="inner_div">foo</div></div>'

正则表达式/<div class="the_class">(.*?)<\/div>/m将返回:

"<div class=\"the_class\"><div class=\"inner_div\">foo</div>"

这种格式错误但可呈现的HTML:

<div class="the_class"><div class="inner_div">foo

更糟糕的是:

'<div class="the_class"><div class="inner_div">foo'[/<div class="the_class">(.*?)<\/div>/m]
=> nil

然而,解析器可以处理两者:

require 'nokogiri'
[
  '<div class="the_class"><div class="inner_div">foo</div></div>',
  '<div class="the_class"><div class="inner_div">foo'
].each do |html|
  doc = Nokogiri.HTML(html)
  puts doc.at('div.the_class').text
end

输出:

foo
foo

是的,你的开始和结束字符串可以是任何东西,但是有很多公认的解析HTML / XML的工具,随着你的任务增长,使用正则表达式的弱点将变得更加明显。

而且,是的,解析器可能会失败。我不得不处理解析器爆炸严重错误的RSS源,但是一些预处理解决了这个问题。