gpt4 book ai didi

使用反向引用和哈希时的 Ruby gsub 问题

转载 作者:数据小太阳 更新时间:2023-10-29 08:19:22 29 4
gpt4 key购买 nike

以下代码定义了一个包含正则表达式(键)和替换(值)的散列。然后它遍历散列并相应地替换字符串。

简单的字符串替换效果很好,但是当我需要在替换之前计算结果时(年到天变化的情况),它不会。预先定义散列是关键。

我错过了什么?任何帮助将不胜感激。

a = "After 45 years we cannot use this thing."

hash = {
/(\d+) years/ => "#{$1.to_f*2}" + ' days',
/cannot/ => 'of course we CAN'
}

hash.each {|k,v|

a.gsub!(k) { v }
}

puts a

谢谢!

最佳答案

String#gsub! 有两种形式,一种是你传入一个字符串作为第二个参数,其中变量引用如 $1$2 被相应的子表达式匹配替换,并且您在其中传入一个 block ,该 block 使用传入子表达式匹配的参数调用。调用 gsub 时使用 block 形式!,但您的哈希中的字符串正在尝试使用传入字符串的形式。

此外,字符串中的变量插值发生在匹配之前;一旦字符串被评估,变量插值就会发生,这是在你的哈希被构造的时候,而为了这个工作,你需要在子表达式替换发生之后发生变量插值(从来没有这种情况;变量插值会发生首先,结果字符串将传递给 gsub! for gsub! 以替换 $1 的子表达式匹配,但是 $1 应该已经被评估并且不再在字符串中,因为插值已经发生)。

现在,如何解决这个问题?好吧,您可能希望将 block 直接存储在散列中(以便在构造散列时不会解释字符串,而是在 gsub! 调用 block 时解释),参数对应于匹配,$1$2 等绑定(bind)到适当的子表达式匹配。为了将一个 block 变成一个可以存储和以后检索的值,你需要向它添加lambda;然后你可以通过在它前面加上 &:

来再次将它作为一个 block 传递
hash = {
/(\d+) years/ => lambda { "#{$1.to_f*2} days" },
/cannot/ => lambda { 'of course we CAN' }
}

hash.each {|k,v|
a.gsub!(k, &v)
}

关于使用反向引用和哈希时的 Ruby gsub 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2082457/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com