【问题标题】:"\\1" vs. $1. Why am i getting different results in Ruby“\\1”与 1 美元。为什么我在 Ruby 中得到不同的结果
【发布时间】:2016-04-12 08:28:01
【问题描述】:

我在较长的脚本中使用它,但一个简短的示例将说明我遇到的问题类型。

my_array2 = ["help", "not", "too"]
my_array2.each do |element|
  element.sub!(/(\w{1})(\w+)/,"\\1")
end

# this gives me the expected ['h','n','t']

如果我这样做

my_array2 = ["help", "not", "too"]
my_array2.each do |element| 
  element.sub!(/(\w{1})(\w+)/, $1)
end

# this gives me ['t','h','n'] (instead of ['h','n','t'] as expected).

发生了什么事?当我使用 $1 返回第一个正则表达式捕获组时,为什么会得到一个“移位”的结果?

【问题讨论】:

  • 您必须使用块形式,即sub!(/.../) { $1 }。否则,$1 指的是上一场比赛。
  • 间接答案是:在Ruby中变量是按值传递的。 $1 在您的sub! 调用之前 的值是传递给sub! 的值,而不是对$1 的引用,它最终将填充到sub! 调用中。跨度>

标签: arrays ruby regex


【解决方案1】:

问题在于$1 是对上一个正则表达式匹配的第一组匹配的引用。它的值是在将其传递给方法 (String#sub!) 时评估的,而不是在匹配完成后评估。

因此,t 来自您之前对\1 的实验。如果你打开一个新的 repl 并运行你的第二个例子,你会得到TypeError: no implicit conversion of nil into String。这是因为$1 在您调用第一个String#sub! 时是nil

【讨论】:

  • 不会返回 ['nil', 'h', 'n'] 吗?为什么最后一个元素的匹配会先结束?
  • @RicmanR,对于第一个问题 - 因为 String#sub 被定义为在替换为 nil 时引发错误。在 irb 中尝试''.sub('', nil)。对于第二个问题 - 第二个代码示例第一个位置的 t 是第一个代码示例中的 "too".gsub... 剩余的。 h 是第二个代码示例中第一个匹配项的剩余部分。 n 是第二个代码示例中的第二个匹配项。
  • 糟糕,刚刚看到您帖子的其余部分。谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-12-21
  • 2021-05-16
  • 1970-01-01
  • 2017-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-07
相关资源
最近更新 更多