5

我正在浏览 about_regular_expressions.rb 并且不明白这里发生了什么:

def test_variables_can_also_be_used_to_access_captures
    assert_equal "Gray, James", "Name:  Gray, James"[/(\w+), (\w+)/]
    assert_equal "Gray", $1
    assert_equal "James", $2
end

在我看来,正则表达式中括号的使用在幕后创建了两个新变量($1 和 $2)。

它是否正确?

但后来我这样做了:

def test_variables_can_also_be_used_to_access_captures
    assert_equal "Gray, James", "Name:  Gray, James"[/(\w+), (\w+)/]
    assert_equal "Smith, Bobert", "Name:  Smith, Bobert"[/(\w+), (\w+)/]
    assert_equal "Smith", $1
    assert_equal "Bobert", $2
end

它捕获了“史密斯”和“博伯特”。我猜每次使用带括号的新正则表达式时,以前的值都会被覆盖?

如果我尝试只捕捉一个词:

def test_variables_can_also_be_used_to_access_captures
    assert_equal "Gray, James", "Name:  Gray, James"[/(\w+), (\w+)/]
    assert_equal "Smith, Bobert", "Name:  Smith, Bobert"[/(\w+), (\w+)/]
    assert_equal "Smith", $1
    assert_equal "Bobert", $2
    assert_equal "Susan,", "Name:  Susan, whatever"[/(\w+),/]
    assert_equal "Susan", $1
    assert_equal nil, $2
end

2 美元不见了……(不再是“鲍勃”)

任何人都可以阐明引擎盖下发生的事情吗?或者指出我正确的方向?

4

2 回答 2

5

你说的对。每次匹配正则表达式时,都会$~, $&, ..., $1, $2, ...覆盖全局变量。在您的上一个示例中,正则表达式没有任何要匹配的内容,$2因为它没有第二个(...)位置,因此nil被分配为$2.

当您想交错使用多个匹配的结果时,我使用的技术是将匹配数据保留为变量。也就是说,在第一次正则表达式匹配之后,立即分配一个变量match1 = $~。然后,继续下一个正则表达式匹配并 do match2 = $~,依此类推。稍后,您可以从这些变量中提取匹配的结果。例如,在进行了几次正则表达式匹配之后,如果您想返回$1在第一次正则表达式匹配时分配的结果,您可以通过match1[1]等调用它。

于 2012-10-18T01:36:36.470 回答
0

检查这个:

"Name:  Gray, James"[0]    # => "N"
"Name:  Gray, James"[/w*/] # => "Name"

在 ruby​​ 中,可以通过索引访问字符串,该索引接受多种类型的对象,也包括正则表达式。

看看语言参考

于 2012-10-18T01:37:45.417 回答