正则表达式验证HTML标记之间的内容

时间:2011-09-10 19:30:04

标签: html ruby regex html-parsing

我很难想出一个RegEx会确认两个标签之间存在一些文字。具体来说,我想确保在同一个表行中找到“TOTAL”和“$ 19.00”文本。

我没有计划嵌套表,所以我不担心嵌套匹配,但我确实想确保我的文本在同一个tr

我的HTML:

<tr style='text-align:right;'>
  <td>shipping:</td>
  <td style='padding-left:3em;'>$17.00</td>
</tr>
<tr style='text-align:right;'>
  <td>TOTAL:</td>
  <td style='padding-left:3em;'>$19.00</td>
</tr>

正则表达式我试过:

/<tr\b[^>]*>(.*?)<\/tr>/m

它很接近,第二个捕获组有我的内容。我需要更改什么才能匹配第二个捕获组?

你可以在Rubular here

上玩它

2 个答案:

答案 0 :(得分:2)

<tr.*?>\s*?<td.*?>TOTAL:<\/td>\s*?<td.*?>\$19\.00<\/td>\s*?<\/tr>

答案 1 :(得分:2)

我认为HTML解析器和一些XPath比正则表达式更好。像这样:

shipping = '//td[normalize-space(text())="shipping:"]/following-sibling::td[normalize-space(text())]'
total    = '//td[normalize-space(text())="TOTAL:"]/following-sibling::td[normalize-space(text())]'
doc = Nokogiri::HTML <<HTML
  <tr style='text-align:right;'>
    <td>  shipping:    </td>
    <td style='padding-left:3em;'>$17.00</td>
  </tr>
  <tr style='text-align:right;'>
    <td>TOTAL:</td>
    <td style='padding-left:3em;'>$19.00</td>
  </tr>
HTML
has_shipping = doc.xpath(shipping).count == 1 # true
has_total    = doc.xpath(total   ).count == 1 # true

但没有$17.00$19.00

doc = Nokogiri::HTML <<HTML
  <tr style='text-align:right;'>
    <td>  shipping:    </td>
    <td style='padding-left:3em;'>    </td>
  </tr>
  <tr style='text-align:right;'>
    <td>TOTAL:</td>
    <td style='padding-left:3em;'></td>
  </tr>
HTML
has_shipping = doc.xpath(shipping).count == 1 # false
has_total    = doc.xpath(total   ).count == 1 # false

如果您想验证价格的格式,那么您可以找到您想要的<td>并应用在您的情况下有意义的任何Enumerable方法:

shipping = '//td[normalize-space(text())="shipping:"]/following-sibling::td'
good_one = doc.xpath(shipping).count { |n| n.content =~ /\A\s*\$\d+\.\d{2}\s*\z/ } == 1