如何访问Ruby正则表达式中相同匹配组的各种出现?

时间:2012-08-21 18:51:42

标签: ruby regex rubular

我有一个有多个匹配的正则表达式。我发现$ 1,$ 2等可以用来访问匹配的组。但是如何访问同一匹配组的多个出现?

请查看下面的rubular页面。

http://rubular.com/r/nqHP1qAqRY

所以现在$ 1给出916而$ 2给出NIL。我怎样才能访问229885?是否有类似$ 1 [1]左右的东西?

3 个答案:

答案 0 :(得分:3)

首先,仅使用正则表达式解析基于xml的数据不是一个好主意。 而是使用库来解析xml文件,比如nokogiri。

但是如果您确定要使用此方法,则需要了解以下内容。 一旦获得(令人愉悦的)匹配,正则表达式引擎就会停止。所以你不能 期望从一个正则表达式调用获得字符串中所有可能的匹配, 你需要在之后使用新的正则表达式匹配来遍历字符串 每个已经发生的比赛。你可以这样做:

# ruby 1.9.x version
regex = /<DATA size="(\d+)"/
str = your_string # Your string to be parsed
position = 0
matches = []
while(match = regex.match(str,position)) do # Until there are no matches anymore
  position = match.end 0 # set position to the end of the last match
  matches << match[1] # add the matched number to the matches-array
end

在此之后,所有解析的数字都应该在matches

但是,既然你的评论暗示,你正在使用 ruby​​ 1.8.x 我会发布另一个 这里的版本,适用于1.8.x(这些版本的方法定义不同)。

# ruby 1.8.x version
regex = /<DATA size="(\d+)"/
str = your_string # Your string to be parsed
matches = []
while(match = regex.match(str)) do # Until there are no matches anymore
  str = match.post_match # set str to the part which is after the match.
  matches << match[1] # add the matched number to the matches-array
end

答案 1 :(得分:1)

扩展我的评论并回答您的问题:

如果要将值存储在数组中,请修改块并收集而不是迭代:

> arr = xml.grep(/<DATA size="(\d+)"/).collect { |d| d.match /\d+/ }
> arr.each { |a| puts "==> #{a}" }
==> 916
==> 229885

|d|是正常的Ruby块参数语法;每个d是匹配的字符串,从中提取数字。它不是最干净的Ruby,虽然它很实用。

仍然建议使用解析器;请注意,rexml版本将是这个(或多或少):

require 'rexml/document'
include REXML
doc = Document.new xml
arr = doc.elements.collect("//DATA") { |d| d.attributes["size"] }
arr.each { |a| puts "==> #{a}" }

将“XML”转换为实际的XML后,您可以获得更多有用的数据:

doc = Document.new xml
arr = doc.elements.collect("//file") do |f|
  name = f.elements["FILENAME"].attributes["path"]
  size = f.elements["DATA"].attributes["size"]
  [name, size]
end

arr.each { |a| puts "#{a[0]}\t#{a[1]}" }

~/Users/1.txt   916
~/Users/2.txt   229885

答案 2 :(得分:0)

在大多数正则表达式的实现中,这是不可能的。 (AFAIK只有.NET可以做到这一点。)

您必须使用scan() Equivalent to Python’s findall() method in Ruby?来使用替代解决方案,例如