我想知道如何才能获得匹配正则表达式中的哪种模式。
我有这个正则表达式(我在Ruby中使用.match):
(?i)(penalty is\W+[0-9]+\W+night)|(penalty of\W+[0-9]+\W+)
现在我知道如何在字符串中返回匹配的文本,但是有没有办法为该字符串获取匹配的字符串和匹配的模式?所以我将得到两个结果:
最好的问候。
答案 0 :(得分:3)
pattern = /(?i)(penalty is\W+[0-9]+\W+night)|(penalty of\W+[0-9]+\W+)/
"penalty of 123 points".match(pattern)
=> #<MatchData "penalty of 123 " 1:nil 2:"penalty of 123 ">
非零捕获数显示模式的哪个部分匹配。您可以通过多种方式获取此值,例如:
"penalty of 123 points".match(pattern).captures
=> [nil, "penalty of 123 "]
# Get the index of the first *non-nil* element:
"penalty of 123 points".match(pattern).captures.find_index(&:itself)
=> 1
因此,根据上述方法链是返回0
还是1
,您将知道第一组或第二组是否匹配。
如果您希望使此代码更透明(更容易理解其工作原理),您还可以考虑使用命名的捕获组,例如:
pattern = /(?i)(?<night>penalty is\W+[0-9]+\W+night)|(?<other>penalty of\W+[0-9]+\W+)/
"penalty of 123 points".match(pattern)
=> #<MatchData "penalty of 123 " night:nil other:"penalty of 123 ">
"penalty of 123 points".match(pattern).named_captures
=> {"night"=>nil, "other"=>"penalty of 123 "}
"penalty of 123 points".match(pattern).named_captures.compact.keys.first
=> "other"
为了更进一步,您还可以将每个“子模式”定义为不同的正则表达式以供将来参考,并将它们连接在一起以进行主匹配,例如:
groups = {
"night" => /(?<night>penalty is\W+[0-9]+\W+night)/i,
"other" => /(?<other>penalty of\W+[0-9]+\W+)/i
]
pattern = Regexp.union(groups)
match_group_name = "penalty of 123 points".match(pattern).named_captures.compact.keys.first
puts "Pattern that matched: #{groups[match_group_name]}"
答案 1 :(得分:2)
REGEXPS = [
/(?<first>penalty is\W+[0-9]+\W+night)/i,
/(?<second>penalty of\W+[0-9]+\W+)/i
].freeze
Regexp.union(REGEXPS) =~ ""
$~.named_captures
答案 2 :(得分:1)
让我们允许任意数量的联合正则表达式,并设计方法以便于测试。
让str
为字符串,regexes
为正则表达式的数组。对于问题中给出的例子,
regexes = [/(?i)(?<night>penalty is\W+[0-9]+\W+night)/,
/(?i)(?<other>penalty of\W+[0-9]+\W+)/]
def doit(str, regexes)
regexes.each do |r|
m = str[r]
return [r, m] unless m.nil?
end
nil
end