str = "cruel world"
#pattern can be /(?<a>.)(?<b>.)/ OR /(?<b>.)(?<a>.)/
#which was inputted by user, we don't know which one will be picked up by user.
pattern = params[:pattern]
请使用str.scan(/#{pattern}/)
或其他匹配方法预期输出:
p a
# ["c", "u", "l", "w", "r"]
p b
# ["r", "e", " ", "o", "l"]
p c
# [ ]
# there is no named group: `?<c>` in this case. However, we should take it if user inputted.
这是我的解决方案:
str = "cruel world"
#case 1
pattern = /(?<a>.)(?<b>.)/
a = Array.new
b = Array.new
c = Array.new
str.scan(/#{pattern}/) do |x|
a << Regexp.last_match(:a) if $~.names.include? "a"
b << Regexp.last_match(:b) if $~.names.include? "b"
c << Regexp.last_match(:c) if $~.names.include? "c"
end
p a
p b
p c
有更好的方法吗?
答案 0 :(得分:2)
这是我的解决方案
def find_named_matches(str, pattern)
names = pattern.names
return Hash[names.zip [[]] * names.size] unless str =~ pattern
Hash[names.zip str.scan(pattern).transpose]
end
并且测试
describe 'find_named_matches' do
example 'no matches' do
find_named_matches('abcabcabc', /(?<a>x.)(?<b>.)/).should == {'a' => [], 'b' => []}
end
example 'simple match' do
find_named_matches('abc', /(?<a>.)/).should == {'a' => %w[a b c]}
end
example 'complex name' do
find_named_matches('abc', /(?<Complex name!>.)/).should == {'Complex name!' => %w[a b c]}
end
example 'two simple variables' do
find_named_matches('cruel world', /(?<a>.)(?<b>.)/).should ==
{'a' => %w[c u l w r], 'b' => %w[r e \ o l]}
end
example 'two simple variables' do
find_named_matches('cruel world', /(?<b>.)(?<a>.)/).should ==
{'b' => %w[c u l w r], 'a' => %w[r e \ o l]}
end
example "three variables and matched chars that aren't captured" do
find_named_matches('afk1bgl2chm3', /(?<a>.)(?<f>.)(?<k>.)./).should ==
{'a' => %w[a b c], 'f' => %w[f g h], 'k' => %w[k l m]}
end
example 'complex regex' do
find_named_matches("the dog's hog is the cat's rat", /(?<nouns>(?:(?<=the |'s ))\w+)/).should ==
{'nouns' => %w[dog hog cat rat]}
end
end