4

我在 Ruby 2.0 中的正则表达式中遇到命名捕获问题。我有一个字符串变量和一个插值的正则表达式:

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

它引发以下异常:

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

但是,插值表达式在没有命名捕获的情况下工作。例如:

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

3 回答 3

6

命名捕获必须使用文字

您遇到了 Ruby 正则表达式库的一些限制。Regexp #=~方法限制命名捕获如下:

  • 如果正则表达式不是文字,则不会发生赋值。
  • 正则表达式插值 ,#{}也会禁用赋值。
  • 如果将正则表达式放在右侧,则不会发生赋值。

您需要决定是否要在正则表达式中命名捕获或插值。您目前不能同时拥有两者。

于 2013-04-08T23:32:14.967 回答
2

分配结果#match;这将作为哈希访问,允许您查找命名的捕获组:

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

或者,给出#match一个块,它将接收匹配结果:

> "hello world".match(/(?<greeting>\w+)/) {|matches| matches[:greeting] }
=> "hello"
于 2013-04-08T23:23:02.723 回答
1

作为两个答案的附录,以使其一目了然:

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"

插值适用于命名捕获,只需使用 MatchData 对象,最容易通过match.

于 2017-04-06T17:43:32.053 回答