为什么String#gsub会使内容翻倍? [英] Why does String#gsub double content?

查看:74
本文介绍了为什么String#gsub会使内容翻倍?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

This seems to be wrong, I expect to get "#main= \\'quotes\\'"

当我不使用转义字符时,它会按预期工作.

when I don't use escape char, then it works as expected.

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

所以逃逸一定与事情有关.

So there must be something to do with escaping.

使用红宝石1.9.2p290

Using ruby 1.9.2p290

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

I need to replace single quotes with back-slash and a quote.

更多不一致之处:

"\\'".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)

这是怎么回事?

推荐答案

You're getting tripped up by the specialness of \' inside a regular expression replacement string:

\0\1\2,... \9\&\`\'\+
用第n个分组的子表达式或整个匹配项,匹配前或匹配项或最高匹配项替换匹配的值.

\0, \1, \2, ... \9, \&, \`, \', \+
Substitutes the value matched by the nth grouped subexpression, or by the entire match, pre- or postmatch, or the highest group.

因此,当您说"\\'"时,双精度\\只是一个反斜杠,结果为\',但这意味着最后一次成功匹配右边的字符串".如果要用转义的单引号替换单引号,则需要更多的转义以超越\'的特殊性:

So when you say "\\'", the double \\ becomes just a single backslash and the result is \' but that means "The string to the right of the last successful match." If you want to replace single quotes with escaped single quotes, you need to escape more to get past the specialness of \':

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

或者避免牙签,并使用方块形式:

Or avoid the toothpicks and use the block form:

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

如果试图转引号,加号甚至是个数字,您会遇到类似的问题.

You would run into similar issues if you were trying to escape backticks, a plus sign, or even a single digit.

这里的总体课程是使用块形式> 用于最琐碎的替换.

The overall lesson here is to prefer the block form of gsub for anything but the most trivial of substitutions.

这篇关于为什么String#gsub会使内容翻倍?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆