“ String#gsub {}”(带有块)如何工作?

vad*_*bar 2 ruby string

当我做,

> "fooo".gsub("o") {puts "Found an 'o'"}
Found an 'o'
Found an 'o'
Found an 'o'
=> "f"
Run Code Online (Sandbox Code Playgroud)

gsub删除所有'o's。这是如何运作的?

我认为gsub将每个字符传递给块,但是由于块对字符本身没有任何作用(如捕获),因此将其删除。

我认为是这种情况,因为当我这样做时

> "fooo".gsub("o"){|ch| ch.upcase}
=> "fOOO"
Run Code Online (Sandbox Code Playgroud)

块正在捕获字符并将其变成大写。但是当我这样做时

> "fooo".gsub("o", "u"){|ch| ch.upcase}
=> "fuuu"
Run Code Online (Sandbox Code Playgroud)

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

我发现Ruby将块插入到使用的方法中yield。(选中此选项),但是我仍然不确定我对第一个代码示例和第三个示例的解释。谁能对此进一步说明?

axi*_*iac 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; 如果指定为a String,则它包含的任何正则表达式元字符都将按字面意义进行解释,例如,\\d将匹配反斜杠,后跟d,而不是数字。

如果replace为a String,它将替换匹配的文本。它可能包含对格式的捕获组的反向引用,形式为\\d,其中d是组号,或\\k<n>,其中n是组名。如果它是双引号引起来的字符串,则两个反向引用都必须在前面加上一个额外的反斜杠。但是,在替换过程中,特殊的匹配变量(例如$&)将不会引用当前匹配项。

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

在块形式中,当前匹配字符串传递作为参数,和变量如$1$2$`$&,和$'将被适当地设定。该块返回的值将代替每次调用的匹配项。

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

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

您问题的答案现在看起来很简单。当仅传递一个参数(模式)时,“该块返回的值将替换为每次调用的匹配项”

文档中没有涉及两个参数一个块,因为这不是有效的组合。似乎当传递两个参数时,String#gsub不要指望一个块并忽略它。

更新资料

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

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

仅带有一个参数且没有任何块,String#gsub将返回一个迭代器,因为它可以找到模式,但没有可替换的字符串。

可以通过三种方式为比赛提供替换(上面引用的文档中描述的前三种情况):

  1. 一个字符串被用来代替所有的匹配; 它通常用于从字符串中删除部分(通过提供空字符串作为替换)或屏蔽它的片段(信用卡号,密码,电子邮件地址等);
  2. 一个散列用于提供为每个匹配不同的替换; 事先知道匹配项时很有用;
  3. 当替换依赖于匹配的子串但事先不知道匹配项时,提供一个;例如,一个块可以将每个匹配的子字符串转换为大写并返回,以String#gsub用作替换。