如何使用ruby中的正则表达式计算子字符串?

时间:2011-04-28 19:20:24

标签: ruby regex string

我有一个非常大的xml文件,我将其作为字符串加载 所以我的XML就像

一样
<publication ID="7728" contentstatus="Unchanged" idID="0b000064800e9e39">
<volume contentstatus="Unchanged" idID="0b0000648151c35d">
  <article ID="5756261" contentstatus="Changed" doi="10.1109/TNB.2011.2145270" idID="0b0000648151d8ca"/>
</volume>

                

我想计算字符串

的出现次数
article ID="5705641" contentstatus="Changed"

如何将ID转换为正则表达式

这是我尝试过的事情

searchstr = 'article ID=\"/[1-9]{7}/\" contentstatus=\"Changed\"'
count = ((xml.scan(searchstr).length)).to_s
puts count

请让我知道如何实现这一目标?

由于

4 个答案:

答案 0 :(得分:4)

我要走出困境,猜猜你是Ruby的新手。首先,没有必要将count转换为字符串来放置它。在您发送给它的任何内容上自动调用to_s。

其次,使用字符串操作处理XML并不是一个好主意。我强烈建议您使用完整的XML解析器,如Nokogiri。

那就是说,你不能在这样的字符串中嵌入一个正则表达式。整个查询字符串需要是一个正则表达式。

这样的东西
/article ID="[1-9]{7}" contentstatus="Changed"/

引号不是正则表达式中的特殊字符,因此您无需转义它们。

如果对Ruby中的正则表达式有疑问,我建议您查看Rubular.com

再一次,我无法强调我真的不容忍尝试通过正则表达式操纵XML。 Nokogiri将使XML的处理更容易,更可靠。

答案 1 :(得分:2)

如果XPath是一个选项,它是选择XML元素的首选方式。您可以使用选择器:

//article[@contentstatus="Changed"]

或者,如果可能的话:

count(//article[@contentstatus="Changed"])

答案 2 :(得分:2)

Nokogiri是我推荐的Ruby XML解析器。它非常强大,现在可能是该语言的标准。

我添加了两篇“文章”,以显示您可以轻松找到并操作内容,而无需依赖正则表达式。

require 'nokogiri'

xml =<<EOT
<publication ID="7728" contentstatus="Unchanged" idID="0b000064800e9e39">
<volume contentstatus="Unchanged" idID="0b0000648151c35d">
  <article ID="5756261" contentstatus="Changed"   doi="10.1109/TNB.2011.2145270" idID="0b0000648151d8ca"/>
  <article ID="5756262" contentstatus="Unchanged" doi="10.1109/TNB.2011.2145270" idID="0b0000648151d8ca"/>
  <article ID="5756263" contentstatus="Changed"   doi="10.1109/TNB.2011.2145270" idID="0b0000648151d8ca"/>
</volume>
EOT

doc = Nokogiri::XML(xml)
puts doc.search('//article[@contentstatus="Changed"]').size.to_s + ' found'

puts doc.search('//article[@contentstatus="Changed"]').map{ |n| "#{ n['ID'] } #{ n['doi'] } #{ n['idID'] }" }

>> 2 found
>> 5756261 10.1109/TNB.2011.2145270 0b0000648151d8ca
>> 5756263 10.1109/TNB.2011.2145270 0b0000648151d8ca

将正则表达式与HTML或XML一起使用的问题是,如果XML发生更改,或者您的XML来自不同的来源或格式不正确,它们将非常容易中断。 Regex从未被设计用于处理这类问题,但解析器却是。您可以在每个标记之后使用行结尾的XML,或者根本不使用行结束,只要XML格式正确,解析器就不会真正关心。一个好的解析器,如Nokogiri甚至可以在XML被破坏时进行修复,以便尝试理解它,但是

答案 3 :(得分:1)

您当前的字符串对我来说几乎是完美的,只需删除数字周围的错误/

searchstr = 'article ID=\"[1-9]{7}\" contentstatus=\"Changed\"'