【发布时间】:2020-01-05 02:12:28
【问题描述】:
我不明白为什么
puts("whit'e bread".gsub("'","\\\'"))
给出的结果为
white breade bread
我希望最终结果应该是
whit\'e bread
【问题讨论】:
我不明白为什么
puts("whit'e bread".gsub("'","\\\'"))
给出的结果为
white breade bread
我希望最终结果应该是
whit\'e bread
【问题讨论】:
String#sub 的文档说明:
如果 replacement 是一个看起来像模式捕获组但实际上不是模式捕获组的字符串,例如"\'",那么它前面必须有两个反斜杠,如 "\\'"。
但是$'是一个global variable,其含义是“最后一次成功匹配右边的字符串。”和替换字符串中的\'含义相同。 p>
现在,回到您的替换字符串,让我们记住,在字符串文字中,反斜杠 (\) 是一个引入转义序列的特殊字符。为了表示自己,反斜杠必须表示为\\。
现在一切都清楚了。替换字符串 "\\\'" 表示反斜杠 (\\) 后跟转义序列 \',表示单引号字符 (')。
(在双引号字符串文字中,没有需要对单引号字符进行转义,但它们前面的反斜杠不会改变结果;在单引号字符串文字中,需要使用转义序列\'对单引号字符进行编码,否则它是字符串的结尾。)
结合以上所说的:
"whit'e bread".gsub("'","\\\'")
将单引号替换为\',即e bread(最后一次成功匹配右侧的字符串),结果为white breade bread。 (替换字符串以粗体显示。)
为了获得预期的结果,您必须使用\\' 作为替换字符串。在代码中将其写为字符串文字的正确方法是"\\\\'"。代码变为:
"whit'e bread".gsub("'","\\\\'")
和it produces the expected result。
Ruby 2.7.0 中String#gsub 的文档描述性更强,并明确表示:
同样,
\&、\'、\`和+分别对应特殊变量$&、$'、$`和$+。 (详情请参阅regexp.rdoc。)
感谢@sergio-tulentsev 在他的answer 中使用的链接。
【讨论】:
gsub的块形式来避免一些反斜杠:"whit'e bread".gsub("'") { |m| '\\' + m }。
\')与其在代码中的字符串表示形式("\\'" 或 '\\\'')混淆。正如我在答案中解释的那样,"\\\'" 与 "\\'" 相同,但不会改变其含义。