Why does capturing named groups in Ruby result in “undefined local variable or method” errors?

人盡茶涼 提交于 2019-12-06 04:21:41

问题


I am having trouble with named captures in regular expressions in Ruby 2.0. I have a string variable and an interpolated regular expression:

str = "hello world"
re = /\w+/
/(?<greeting>#{re})/ =~ str
greeting

It raises the following exception:

prova.rb:4:in <main>': undefined local variable or methodgreeting' for main:Object (NameError)
shell returned 1

However, the interpolated expression works without named captures. For example:

/(#{re})/ =~ str
$1
# => "hello"

回答1:


Named Captures Must Use Literals

You are encountering some limitations of Ruby's regular expression library. The Regexp#=~ method limits named captures as follows:

  • The assignment does not occur if the regexp is not a literal.
  • A regexp interpolation, #{}, also disables the assignment.
  • The assignment does not occur if the regexp is placed on the right hand side.

You'll need to decide whether you want named captures or interpolation in your regular expressions. You currently cannot have both.




回答2:


Assign the result of #match; this will be accessible as a hash that allows you to look up your named capture groups:

> matches = "hello world".match(/(?<greeting>\w+)/)
=> #<MatchData "hello" greeting:"hello">
> matches[:greeting]
=> "hello"

Alternately, give #match a block, which will receive the match results:

> "hello world".match(/(?<greeting>\w+)/) {|matches| matches[:greeting] }
=> "hello"



回答3:


As an addendum to both answers in order to make it crystal clear:

str = "hello world"
# => "hello world"
re = /\w+/
# => /\w+/
re2 = /(?<greeting>#{re})/
# => /(?<greeting>(?-mix:\w+))/
md = re2.match str
# => #<MatchData "hello" greeting:"hello">
md[:greeting]
# => "hello"

Interpolation is fine with named captures, just use the MatchData object, most easily returned via match.



来源:https://stackoverflow.com/questions/15890729/why-does-capturing-named-groups-in-ruby-result-in-undefined-local-variable-or-m

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!