2012-03-03 65 views
0
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 

有沒有更好的辦法?

回答

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 
+0

謝謝。這個解決方案是否仍然覆蓋名爲'c'的情況可能存在或不存在? – 2012-03-03 15:30:07

+0

看看測試... – 2012-03-03 18:34:39

+0

非常感謝:D – 2012-03-03 18:56:31