Как определить именованную группу, если пользователь вводит регулярное выражение - PullRequest
0 голосов
/ 03 марта 2012
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 Ответ

2 голосов
/ 03 марта 2012

Вот мое решение

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...