2

有一段代码:

 def test_sub_is_like_find_and_replace
    assert_equal "one t-three", "one two-three".sub(/(t\w*)/) { $1[0, 1] }
 end

我发现很难理解{ }大括号之间的内容。谁能解释一下吗?

4

3 回答 3

5

{...}一个块。Ruby 会将匹配的值传递给块,并将块的返回值替换回字符串。String#sub文档更全面地解释了这一点:

在块形式中,当前匹配字符串作为参数传入,$1、$2、$`、$&、$'等变量会被适当设置。块返回的值将替换每次调用的匹配项。

编辑:根据迈克尔的评论,如果您对此感到困惑$1[0, 1],这只是获取第一个捕获 ( $1) 并获取它的子字符串(特别是第一个字符)。$1 是一个全局变量,设置为正则表达式之后的第一个捕获的内容(以真正的 Perl 方式),并且由于它是一个字符串,因此该#[]运算符用于从索引 0 开始获取它的子字符串,长度为 1。

于 2013-05-24T20:17:43.573 回答
2

sub方法接受两个参数,第一个是要替换的文本,第二个是替换,或者一个参数是要替换的文本和一个定义如何处理替换的块。

如果您不能将替换定义为简单字符串,则 block 方法很有用。

例如:

"foo".sub(/(\w)/) { $1.upcase }
# => "Foo"

"foo".sub(/(\w+)/) { $1.upcase }
# => "FOO"

gsub方法的工作方式相同,但不止一次应用:

"foo".gsub(/(\w)/) { $1.upcase }
# => "FOO"

在所有情况下,$1指的是括号中捕获的内容(\w)

你的代码,图解

r = "one two-three".sub(/(t\w*)/) do 
  $1 # => "two"
  $1[0, 1] # => "t"
end

r # => "one t-three"
于 2013-05-24T20:19:47.903 回答
0

sub正在接受一个正则表达式。这$1是一个保留的全局变量,包含正则表达式的匹配项。

括号表示使用的代码块,它将用块返回的字符串替换匹配项。在这种情况下

puts $1
#=> "two"
puts $1[0, 1]
#=> "t"
于 2013-05-24T20:21:32.507 回答