用反斜杠单引号替换单引号

48

我有一个非常大的字符串,需要对其中所有单引号进行转义,这样我才能将其提供给JavaScript而不会出现错误。由于外部字符串不受我的控制,因此我无法更改源数据。

示例:

Cote d'Ivoir  -> Cote d\'Ivoir  

(实际字符串非常长,包含许多单引号)

我尝试使用gsub处理该字符串,但无法使其工作:

a = "Cote d'Ivoir"
a.gsub("'", "\\\'")

但这给了我:

=> "Cote dIvoirIvoir"

我也尝试了:

a.gsub("'", 92.chr + 39.chr)

但得到了相同的结果;我知道这与正则表达式有关,但我从未理解过它们。


你可能还需要考虑转义双引号,因为有人可以通过输入 My Nefarious" Country 作为他们的国家来破坏你的程序。这就是Rails使用他们的 escape_javascript 助手所做的事情。http://api.rubyonrails.org/classes/ActionView/Helpers/JavaScriptHelper.html - aaron-coding
3个回答

59
这里的%q分隔符非常方便:
# %q(a string) is equivalent to a single-quoted string
puts "Cote d'Ivoir".gsub("'", %q(\\\')) #=> Cote d\'Ivoir

5
实际上,您的示例返回的是"Cote d\'Ivoir"而不是所需的"Cote d'Ivoir"结果。 - Dave Sag
7
@Dave: p ("Cote d'Ivoir".gsub("'", %q(\\\'))).size 返回的结果是13。(IRB使用\使转义字符可见) - steenslag
为了在不使用%q分隔符的情况下使用它,您的替换将是.gsub("'", "\\\\'")。五个反斜杠和一个撇号也会返回相同的结果。无论如何,我更喜欢@steenslag的答案,更容易阅读。 - Michael

22
问题在于 gsub 替换中的 \' 表示 "匹配后的字符串部分"。
最好使用块语法:
a = "Cote d'Ivoir"
a.gsub(/'/) {|s| "\\'"}
# => "Cote d\\'Ivoir"
或者使用哈希语法:
a.gsub(/'/, {"'" => "\\'"})

还有一种骚操作的解决方法:

a.gsub(/'/, '\#').gsub(/#/, "'")

1
所有这些例子都给出了“Cote d\'Ivoir”,而不是“Cote d'Ivoir”。 - Dave Sag
@DaveSag - 请记住,在 " 字符串中,\ 需要进行转义。该字符串包含 \',表示为 "\\'" - Chowlett
展示 REPL 如何处理 "\" 的最简单方法是输出字符串:str = "Cote d'Ivoire" #=> "Cote d'Ivoire" str = "Cote d\'Ivoire" #=> "Cote d'Ivoire" str = "Cote d\\'Ivoire" #=> "Cote d\\'Ivoire" puts str Cote d\'Ivoire #=> nil - iNulty

0
# prepare a text file containing [  abcd\'efg  ]
require "pathname"
backslashed_text = Pathname("/path/to/the/text/file.txt").readlines.first.strip
# puts backslashed_text => abcd\'efg

unslashed_text = "abcd'efg"
unslashed_text.gsub("'", Regexp.escape(%q|\'|)) == backslashed_text # true
# puts unslashed_text.gsub("'", Regexp.escape(%q|\'|)) => abcd\'efg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接