regex-如何获取字符串中所有出现的Ruby正则表达式的匹配数据?

对于字符串中每个正则表达式的出现,我都需要MatchData。 这与“正则表达式的所有匹配项”中建议的扫描方法不同,因为这只会给我一个字符串数组(我需要完整的MatchData,以获取开始和结束信息,等等)。

input = "abc12def34ghijklmno567pqrs"
numbers = /\d+/

numbers.match input # #<MatchData "12"> (only the first match)
input.scan numbers  # ["12", "34", "567"] (all matches, but only the strings)

我怀疑有些方法被我忽略了。 有什么建议吗?

Joshua Flanagan asked 2020-08-10T18:11:08Z
5个解决方案
66 votes

你要

"abc12def34ghijklmno567pqrs".to_enum(:scan, /\d+/).map { Regexp.last_match }

这给你

[#<MatchData "12">, #<MatchData "34">, #<MatchData "567">] 

如您所见,“技巧”是建立一个枚举器,以获取每个last_match。

i-blis answered 2020-08-10T18:11:22Z
9 votes

我当前的解决方案是向Regexp添加each_match方法:

class Regexp
  def each_match(str)
    start = 0
    while matchdata = self.match(str, start)
      yield matchdata
      start = matchdata.end(0)
    end
  end
end

现在我可以做:

numbers.each_match input do |match|
  puts "Found #{match[0]} at #{match.begin(0)} until #{match.end(0)}"
end

告诉我有更好的方法。

Joshua Flanagan answered 2020-08-10T18:11:51Z
7 votes

我将其放在此处,以防万一通过相应的Google搜索提供代码:

input = "abc12def34ghijklmno567pqrs"
numbers = /\d+/
input.gsub(numbers) { |m| p $~ }

结果按要求:

⇒ #<MatchData "12">
⇒ #<MatchData "34">
⇒ #<MatchData "567">

详细说明。

Aleksei Matiushkin answered 2020-08-10T18:12:19Z
1 votes

我很惊讶,没有人提到Ruby标准库中包含的惊人的StringScanner类:

require 'strscan'

s = StringScanner.new('abc12def34ghijklmno567pqrs')

while s.skip_until(/\d+/)
  num, offset = s.matched.to_i, [s.pos - s.matched_size, s.pos - 1]

  # ..
end

不,它不会为您提供MatchData对象,但会为您提供基于索引的字符串接口。

mwp answered 2020-08-10T18:12:44Z
0 votes
input = "abc12def34ghijklmno567pqrs"
n = Regexp.new("\\d+")
[n.match(input)].tap { |a| a << n.match(input,a.last().end(0)+1) until a.last().nil? }[0..-2]

=> [#<MatchData "12">, #<MatchData "34">, #<MatchData "567">]
Lyndon S answered 2020-08-10T18:13:00Z
translate from https://stackoverflow.com:/questions/6804557/how-do-i-get-the-match-data-for-all-occurrences-of-a-ruby-regular-expression-in