Ruby “gsub”和“gsub!”有何不同当使用散列键作为模式来替换其值时?

Ruby “gsub”和“gsub!”有何不同当使用散列键作为模式来替换其值时?,ruby,regex,hash,Ruby,Regex,Hash,我用了gsub以哈希值替换哈希键的匹配项。例如: def replace_string(string = "@ReplaceMe[xyz]@@ReplaceMe[123]@Hello") generator_replacements = { "@ReplaceMe[xyz]@" => "Time", "@ReplaceMe[123]@" => "Date" } generator_replacements.each{ |generator, rep

我用了
gsub
以哈希值替换哈希键的匹配项。例如:

def replace_string(string = "@ReplaceMe[xyz]@@ReplaceMe[123]@Hello")
  generator_replacements = {
    "@ReplaceMe[xyz]@" => "Time",
    "@ReplaceMe[123]@" => "Date"
  }
  generator_replacements.each{
    |generator, replacement|
    string = string.gsub!(generator.to_s, replacement.to_s)
    puts string
  }
end

replace_string
产出:

  • TimeDateHello
  • TimeDateHello
  • 我不明白为什么
    gsub一次替换所有哈希键,而不是每次迭代。当我尝试使用
    gsub
    时,它会用每次迭代替换:

  • Time@ReplaceMe[123]@你好
  • TimeDateHello

  • 有人能解释一下为什么会发生这种情况吗?

    我已经编辑了您的代码,使其工作原理如下所示:

    def replace_string(generated_string = "@ReplaceMe[xyz]@@ReplaceMe[123]@Hello")
      generator_replacements = {
        "@ReplaceMe[xyz]@" => "Time",
        "@ReplaceMe[123]@" => "Date"
      }
      generator_replacements.each do |generator, replacement|
        string = generated_string.gsub(generator.to_s, replacement.to_s)
        puts string
      end
    end
    
    使用此代码,使用
    gsub
    我得到:

    Time@ReplaceMe[123]@Hello
    @ReplaceMe[xyz]@DateHello
    
    Time@ReplaceMe[123]@Hello
    TimeDateHello
    
    使用
    gsub我得到:

    Time@ReplaceMe[123]@Hello
    @ReplaceMe[xyz]@DateHello
    
    Time@ReplaceMe[123]@Hello
    TimeDateHello
    

    原因是
    gsub
    修改现有字符串,其中as
    gsub
    不修改现有字符串。这有助于回答您的问题吗?

    在这方面没有区别。
    每个
    循环都是逐元素执行的,既不是
    gsub
    也不是
    gsub可以预见未来

    此代码:

    replacements = { 'foo' => 'hello', 'bar' => 'world' }
    string = 'foo bar!'
    replacements.each do |placeholder, value|
      string = string.gsub(placeholder, value)
    end
    string #=> 'hello world!'
    
    相当于:

    string = 'foo bar!'
    string = string.gsub('foo', 'hello') #=> "hello bar!"
    string = string.gsub('bar', 'world') #=> "hello world!"
    string #=> 'hello world!'
    
    使用
    gsub您可以编写:

    string = 'foo bar!'
    string.gsub!('foo', 'hello') #=> "hello bar!"
    string.gsub!('bar', 'world') #=> "hello world!"
    string #=> 'hello world!'
    
    主要区别在于
    gsub
    更改接收器的位置,而
    gsub
    返回一个新字符串(因此需要将其分配回
    string

    要一次执行多个替换,可以将哈希传递给
    gsub

    string = 'foo bar!'
    string.gsub(/foo|bar/, { 'foo' => 'hello', 'bar' => 'world' })
    #=> "hello world!"
    
    也可以通过编程方式生成正则表达式:

    replacements = { 'foo' => 'hello', 'bar' => 'world' }
    string = 'foo bar!'
    string.gsub(Regexp.union(replacements.keys), replacements)
    #=> "hello world!"
    

    这不是有效的语法。在Ruby中,方法定义周围不使用大括号。生成的字符串是什么?我有一种感觉,这不是您实际的工作(或非工作)代码。请编辑您的问题以包含您的实际代码。您能想出一个使用不太神秘的占位符名称的示例吗?生成的字符串是什么?@Jordan这不是我的实际代码,对吗。出于保密原因,我需要在这里发布之前删除实际变量名和数据的任何痕迹。我现在已经将
    生成的_string
    更正为
    string
    ,如果是这样,那么
    gsub
    gsub之间没有区别除了
    gsub
    覆盖
    字符串
    ,那么为什么我的函数不输出Time@ReplaceMe[123]@Hello then TimeDateHello?@QCFia您的代码无效,我们不知道如何调用您的方法。请编辑您的问题并包含您的实际代码。现在这更有意义吗???@QCFia无论我使用
    gsub
    还是
    gsub,我都会得到相同的输出