具有命名捕获组的正则表达式获取Ruby中的所有匹配项

mlz*_*boy 28 ruby regex

我有一个字符串:

s="123--abc,123--abc,123--abc"
Run Code Online (Sandbox Code Playgroud)

我尝试使用Ruby 1.9的新功能"命名组"来获取所有命名的组信息:

/(?<number>\d*)--(?<chars>\s*)/
Run Code Online (Sandbox Code Playgroud)

是否有像Python这样的API findall返回一个matchdata集合?在这种情况下,我需要返回两个匹配,因为123abc重复两次.每个匹配数据都包含每个命名捕获信息的详细信息,因此我可以使用它m['number']来获取匹配值.

Nak*_*lon 30

命名捕获仅适用于一个匹配结果.
Ruby的类比findallString#scan.您可以将scan结果用作数组,也可以将块传递给它:

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"
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,似乎红宝石不支持命名的捕获功能 (2认同)
  • @mlzboy,不,它完全支持命名捕获功能 - 它只是以你想要的另一种方式工作 (2认同)
  • 实际上`scan`可以正确支持命名捕获,你只需要在块中使用`$ ~`(参见[Mark Hubbart的回答](http://stackoverflow.com/a/13817639/15813))来访问`MatchData `对象. (2认同)

mar*_*ius 22

超级迟到,但这是一种复制String#scan的简单方法,但获取matchdata:

matches = []
foo.scan(regex){ matches << $~ }
Run Code Online (Sandbox Code Playgroud)

matches 现在包含与扫描字符串相对应的MatchData对象.

  • `$ LAST_MATCH_INFO`是`$ ~`的类似"英语"变量,希望它为想要更易读代码的人保存一些谷歌搜索. (5认同)

Umu*_*kan 9

您可以使用names方法从regexp中提取已使用的变量.所以我做的是,我使用常规scan方法来获取匹配,然后压缩名称和每个匹配来创建一个Hash.

class String
  def scan2(regexp)
    names = regexp.names
    scan(regexp).collect do |match|
      Hash[names.zip(match)]
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

用法:

>> "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"}]
Run Code Online (Sandbox Code Playgroud)