Regex with named capture groups getting all matches in Ruby
I have a string:
s="123--abc,123--abc,123--abc"
I tried using Ruby 1.9's new feature "named groups" to fetch all named group info:
/(?<number>d*)--(?<chars>s*)/
Is there an API like Python's findall
which returns a matchdata
collection? In this case I need to return two matches, because 123
and abc
repeat twice. Each match data contains of detail of each named capture info so I can use m['number']
to get the match value.
Named captures are suitable only for one matching result.
Ruby's analogue of findall
is String#scan
. You can either use scan
result as an array, or pass a block to it:
irb> s = "123--abc,123--abc,123--abc"
=> "123--abc,123--abc,123--abc"
irb> s.scan(/(d*)--([a-z]*)/)
=> [["123", "abc"], ["123", "abc"], ["123", "abc"]]
irb> s.scan(/(d*)--([a-z]*)/) do |number, chars|
irb* p [number,chars]
irb> end
["123", "abc"]
["123", "abc"]
["123", "abc"]
=> "123--abc,123--abc,123--abc"
Chiming in super-late, but here's a simple way of replicating String#scan but getting the matchdata instead:
matches = []
foo.scan(regex){ matches << $~ }
matches
now contains the MatchData objects that correspond to scanning the string.
You can extract the used variables from the regexp using names
method. So what I did is, I used regular scan
method to get the matches, then zipped names and every match to create a Hash
.
class String
def scan2(regexp)
names = regexp.names
scan(regexp).collect do |match|
Hash[names.zip(match)]
end
end
end
Usage:
>> "aaa http://www.google.com.tr aaa https://www.yahoo.com.tr ddd".scan2 /(?<url>(?<protocol>https?)://[S]+)/
=> [{"url"=>"http://www.google.com.tr", "protocol"=>"http"}, {"url"=>"https://www.yahoo.com.tr", "protocol"=>"https"}]
链接地址: http://www.djcxy.com/p/74822.html
上一篇: 正则表达式用Go编程语言查找命名的捕获组