Ruby Koans:正则表达式括号“捕获”匹配的内容?

Rob*_*ert 5 ruby

我正在浏览 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
Run Code Online (Sandbox Code Playgroud)

在我看来,在正则表达式中使用括号会在幕后创建两个新变量($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
Run Code Online (Sandbox Code Playgroud)

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

如果我尝试只捕获一个单词:

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
Run Code Online (Sandbox Code Playgroud)

2 美元不见了......(不再是“罗伯特”)

谁能解释一下幕后发生的事情吗?或者为我指明正确的方向?

saw*_*awa 5

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

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