为什么String#gsub包含双重内容


s = "#main= 'quotes'
s.gsub "'", "\'" # => "#main= quotes'quotes"

这似乎是错误的,我希望得到"#main= \'quotes\'"

当我不使用escape-char时,它会按预期工作。

s.gsub "'", "*" # => "#main= *quotes*"

所以逃跑一定有什么关系。

使用ruby 1.9.2p90

我需要用反斜杠和引号替换单引号。

更多不一致:

"\'".length # => 2
"\*".length # => 2
# As expected
"'".gsub("'", "\*").length # => 2
"'a'".gsub("'", "\*") # => "\*a\*" (length==5)
# WTF next:
"'".gsub("'", "\'").length # => 0
# Doubling the content?
"'a'".gsub("'", "\'") # => "a'a" (length==3)

这是怎么回事?

您被正则表达式替换字符串中'的特殊性绊倒了

12。。。9&`'+
替换由第n个分组子表达式匹配的值,或由整个匹配、匹配前或匹配后或最高组匹配的值。

因此,当你说"\'"时,双\变成了一个反斜杠,结果是',但这意味着"最后一次成功匹配右侧的字符串"。如果你想用转义的单引号替换单引号,你需要转义更多的单引号,以克服'的特殊性:

s.gsub("'", "\\'")

或者避开牙签,使用块形式:

s.gsub("'") { |m| '\' + m }

如果你试图逃避回溯、加号,甚至个位数,你也会遇到类似的问题。

这里的总体教训是,除了最琐碎的替换之外,更喜欢gsub的块形式。

s = "#main = 'quotes'
s.gsub "'", "\\'"

由于,它与\等效,如果你想得到一个双反斜杠,你必须放四个一。

您还需要退出\:

s.gsub "'", "\\'"

输出

"#main= \'quotes\'"

在一个外部论坛上找到了一个很好的解释:

理解IMHO的关键点是反斜杠在替换字符串。所以,每当一个人想要有一个文字替换字符串中的反斜杠需要对其进行转义,因此有两个反斜杠。巧合的是,反斜杠在字符串(即使是单引号字符串(。所以你需要两个层次转义,在屏幕上为一个文本生成2*2=4个反斜杠替换反斜杠。

相关内容

  • 没有找到相关文章

最新更新