如果用户输入正则表达式,如何确定命名组

时间:2012-03-03 14:25:08

标签: ruby regex

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 

有更好的方法吗?

1 个答案:

答案 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