为什么 String#gsub 的内容加倍?

发布于 2024-11-29 12:11:14 字数 662 浏览 2 评论 0原文

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

这似乎是错误的,我希望

当我不使用转义字符时得到 "#main= \\'quotes\\'" ,然后它按预期工作。

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

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

使用 ruby​​ 1.9.2p290

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

甚至更多的矛盾:

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

这里发生了什么?

s = "#main= 'quotes'
s.gsub "'", "\\'" # => "#main= quotes'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.

Using ruby 1.9.2p290

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

Even more inconsistencies:

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

What is going on here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

万水千山粽是情ミ 2024-12-06 12:11:14

您会被 \' 在正则表达式替换字符串内

<代码>\0、<代码>\1、<代码>\2、...<代码>\9、<代码>\&、\`\'\+
替换第 n 个分组子表达式、整个匹配、匹配前或匹配后或最高组匹配的值。

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

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

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

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

如果你试图转义反引号、加号、甚至单个数字。

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

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

\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.

洛阳烟雨空心柳 2024-12-06 12:11:14
s = "#main = 'quotes'

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

由于 \ 它与 \\ 等效,如果您想获得双反斜杠,则必须输入四个反斜杠。

s = "#main = 'quotes'

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

Since \it's \\equivalent if you want to get a double backslash you have to put four of ones.

放血 2024-12-06 12:11:14

您还需要转义 \:

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

输出

"#main= \\'quotes\\'"

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

理解恕我直言的关键点是反斜杠在
替换字符串。所以,每当一个人想要一个字面意义的时候
替换字符串中的反斜杠需要转义它,因此
有[两个]反斜杠。巧合的是,反斜杠在
字符串(即使在单引号字符串中)。所以你需要两个级别
转义,在屏幕上为一个文字生成 2 * 2 = 4 个反斜杠
替换反斜杠。

来源

You need to escape the \ as well:

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

Outputs

"#main= \\'quotes\\'"

A good explanation found on an outside forum:

The key point to understand IMHO is that a backslash is special in
replacement strings. So, whenever one wants to have a literal
backslash in a replacement string one needs to escape it and hence
have [two] backslashes. Coincidentally a backslash is also special in a
string (even in a single quoted string). So you need two levels of
escaping, makes 2 * 2 = 4 backslashes on the screen for one literal
replacement backslash.

source

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文