ruby - 'String#gsub { }'(带 block )如何工作?

标签 ruby string

当我这样做的时候,

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

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

我认为 gsub 将每个字符传递给 block ,但由于 block 对字符本身没有做任何事情(比如捕捉它),它被丢弃了。

我认为是这样的,因为当我这样做的时候

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

该 block 正在捕获字符并将其转换为大写。 但是当我这样做的时候,

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

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

我发现 Ruby 使用 yield 将 block 插入到方法中。 (检查 this )但我仍然不确定我对第一个代码示例和第三个示例的解释。谁能进一步说明这一点?

最佳答案

方法文档 String#gsub 解释它是如何工作的,这取决于它获得的参数:

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

Returns a copy of str with all occurrences of pattern substituted for the second argument. The pattern is typically a Regexp; if given as a String, any regular expression metacharacters it contains will be interpreted literally, e.g. \\d will match a backslash followed by d, instead of a digit.

If replacement is a String it will be substituted for the matched text. It may contain back-references to the pattern’s capture groups of the form \\d, where d is a group number, or \\k<n>, where n is a group name. If it is a double-quoted string, both back-references must be preceded by an additional backslash. However, within replacement the special match variables, such as $&, will not refer to the current match.

If the second argument is a Hash, and the matched text is one of its keys, the corresponding value is the replacement string.

In the block form, the current match string is passed in as a parameter, and variables such as $1, $2, $`, $&, and $' will be set appropriately. The value returned by the block will be substituted for the match on each call.

The result inherits any tainting in the original string or any supplied replacement string.

When neither a block nor a second argument is supplied, an Enumerator is returned.

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

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

更新

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

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

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

可以通过三种方式为其提供匹配项的替换(前三种情况在上面引用的文档中有所描述):

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

关于ruby - 'String#gsub { }'(带 block )如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46357497/

相关文章:

c - "%"符号后面的数字有什么作用?

Ruby 确定季节(秋季、冬季、 Spring 或夏季)

string - 如何使用 sscanf 或 fscanf 从文件中读取字符串?

c# - 在 C# .NET 中调用 Ruby 或 Python API

ruby - ruby 中 rspec 测试的实现问题

javascript - 使用 jQuery 更改 HTML 字符串 : wont update the string

regex - 匹配字符串中最后一个数字的正则表达式

ruby-on-rails - 使用 ruby​​ gsub 和正则表达式进行更智能的字符替换

Ruby Koan 151 引发异常

ruby - 我怎样才能在 each_char 中执行此操作?