'String#gsub {}'(带块)如何工作?

时间:2017-09-22 05:34:44

标签: ruby string

当我这样做时,

> "fooo".gsub("o") {puts "Found an 'o'"}
Found an 'o'
Found an 'o'
Found an 'o'
=> "f"

gsub删除所有'o'个。这是如何工作的?

我认为gsub将每个字符传递给块,但由于块对字符本身没有任何作用(比如捕获它),所以它被删除了。

我认为情况就是这样,因为我做的时候

> "fooo".gsub("o"){|ch| ch.upcase}
=> "fOOO"

该块正在捕获角色并将其转换为大写。 但是当我这样做时,

> "fooo".gsub("o", "u"){|ch| ch.upcase}
=> "fuuu"

在这种情况下Ruby如何处理块?

我发现Ruby使用yield将块插入方法中。 (检查this)但我仍然不确定我对第一个代码示例和第三个示例的解释。任何人都可以对此有所了解吗?

2 个答案:

答案 0 :(得分:6)

方法String#gsub的文档解释了它的工作原理,具体取决于它获得的参数:

  

gsub(pattern, replacement)new_str
  gsub(pattern, hash)new_str
  gsub(pattern) {|match| block }new_str
  gsub(pattern)enumerator

     

返回 str 的副本,其中所有出现的 pattern 替换为第二个参数。 模式通常为Regexp;如果作为String给出,则它包含的任何正则表达式元字符将按字面解释,例如\\d将匹配后跟d的反斜杠,而不是数字。

     

如果替换String,则会替换匹配的文本。它可能包含对\\d形式的模式捕获组的反向引用,其中d是组号,或\\k<n>,其中n是组名。如果它是双引号字符串,则两个反向引用都必须以额外的反斜杠开头。但是,在替换中,特殊匹配变量(例如$&)不会引用当前匹配。

     

如果第二个参数是Hash,并且匹配的文本是其中一个键,则相应的值是替换字符串。

     

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

     

结果继承了原始字符串或任何提供的替换字符串中的任何污点。

     

如果既没有提供块也没有提供第二个参数,则返回Enumerator

你的问题的答案现在看起来很简单。 当只传递一个参数(模式)时,&#34;该块返回的值将替换每次调用的匹配&#34;

两个参数一个块是文档未涵盖的情况,因为它不是有效的组合。似乎当传递两个参数时,$'并不期望一个块并忽略它。

更新

String#gsub的目的是进行&#34;全局搜索&#34;,即查找所有出现的某些字符串或模式并替换它们。

第一个参数 pattern 是要搜索的字符串或模式。没什么特别的。它可以是字符串或正则表达式。 String#gsub搜索它并找到零个或多个匹配项(出现次数)。

只有一个参数且没有块,String#gsub返回一个迭代器,因为它可以找到模式,但它没有要使用的替换字符串。

有三种方法可以为匹配提供替换(前面引用的文档中描述的前三种情况):

  1. String 用于替换所有匹配项;它通常用于从字符串中删除部分(通过提供空字符串作为替换)或掩盖它的片段(信用卡号,密码,电子邮件地址等);
  2. 哈希用于为每场比赛提供不同的替换;当事先知道比赛时,它很有用;
  3. 当替换取决于匹配的子串但是事先不知道匹配时,提供;例如,一个块可以将每个匹配的子字符串转换为大写并返回它,让String#gsub将其用作替换。

答案 1 :(得分:4)

puts的返回值为nil,由to_s转换为空白。因此,每个匹配的"o"都将替换为空白。