像 $1 这样的变量是在执行正则表达式匹配之后才被填充的。简化您的示例:
s.gsub('original(value)', "replacement#{$1}")
表达式 "replacement#{$1}" 会在调用 gsub 函数之前被求值。因此,$1 将保留自某个之前的正则表达式任务。(这就是为什么您的第二次尝试有效——它使用了第一次尝试中的 $1)
有几种选项可以解决此问题。gsub 具有多种功能。
我倾向于向 gsub 传递一个代码块。该代码块在正则表达式匹配之后被求值,因此 $1 会按您的预期工作:
s.gsub('original(value)') { |match| "replacement#{$1}" }
或者,您可以使用 gsub 的“反向引用”功能。我不太喜欢这种语法,但它确实有效。与其使用 "replacement#{$1}",您可以使用 'replacement\1'(或 \2、\3 等)。
s.gsub('original(value)', 'replacement\1')