我正在浏览 Koans 教程(这是一种很好的学习方式),我遇到了这样的说法:
assert_equal __, "one two-three".sub(/(t\w*)/) { $1[0, 1] }
在此声明中,__ 是我应该放置预期结果以使测试正确执行的位置。我盯着这个看了一会儿,把它的大部分拆开,但我无法弄清楚最后一点是什么意思:
{ $1[0, 1] }
预期的答案是:
"one t-three"
我期待:
"t-t"
最佳答案
{ $1[0, 1] }
是一个包含表达式 $1[0,1]
的 block 。 $1[0,1]
的计算结果为字符串 $1
的第一个字符,其中包含最后匹配的正则表达式的第一个捕获组的内容。
当使用正则表达式和 block 调用 sub
时,它将找到正则表达式的第一个匹配项,调用 block ,然后用 block 的结果替换匹配的子字符串。
所以 "one two-three".sub(/(t\w*)/) { $1[0, 1] }
搜索模式 t\w*
。这会找到子字符串 "two"
。因为整个事情都在一个捕获组中,所以这个子字符串存储在 $1
中。现在调用该 block 并返回 "two"[0,1]
,即 "t"
。所以 “two”
被替换为 “t”
并且你得到 “one t-three”
。
需要注意的重要一点是 sub
与 gsub
不同,它只会替换第一次出现的模式,而不是永远不会出现的模式。
关于Ruby 正则表达式问题 wrt String 上的 sub 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4626425/