我有以下程序:
args = ["a", "b"]
cmd_args = args.map{|x| x.inspect}
str = cmd_args.join(' ')
puts str
输出为:
"a" "b"
我希望输出如下所示(用
'
而不是 "
引用子字符串):
'a' 'b'
我不想在字符串
gsub
之后执行 inspect
,因为在我的真实系统中,子字符串可能包含 "
。例如:
args = ['a"c', "b"]
cmd_args = args.map{|x| x.inspect.gsub('"', '\'')}
str = cmd_args.join(' ')
puts str
将输出:
'a\'c' 'b'
a 和 c 之间的
"
被错误替换。我的预期输出是:
'a"c' 'b'
如何进行字符串检查以使用
'
而不是 "
来引用字符串?
s = 'a"c'.inspect
s[0] = s[-1] = "'"
puts s.gsub("\\\"", "\"") #=> 'a"c'
您不能强制
String#inspect
使用单引号而不重写或覆盖它。
您可以替换
x.inspect
,而不是 "'#{x}'"
,但随后您必须确保转义 '
中出现的任何 x
字符。
在这里,正在工作:
args = ["a", "b"]
cmd_args = args.map{|x| "'#{x}'" }
str = cmd_args.join(' ')
puts str
输出为:
'a' 'b'
如果您关心通过反斜杠正确转义
'
以及因此的 \
,则两个答案的解决方案都将失败。请参阅 raimo 对 sawa 的回答的评论。 user513951的解决方案以同样的方式失败:
irb(main):040> x = "b'c"; puts "'#{x}'"
'b'c'
可以使用以下函数正确转义
'
和\
:
def inspect_str_single_quote(s)
"'" + s.gsub(/\\/, "\\\\").gsub(/'/, "\\\\'") + "'"
end
如果您不仅希望能够序列化纯字符串,还希望能够序列化任意数据结构(可能包含字符串),您可能需要推出自己的
inspect
版本。这是一个草图,概述了如何完成它,并为读者留下了待办事项:
def inspect_single_quote(value)
case value
when String
inspect_str_single_quote( value
when Array
"[" + value.map { |item| inspect_str_single_quote(item) }.join(", ") + "]"
when Hash
TODO follow "Array" example
when Set
TODO follow "Array" example
when Range # to handle e.g. string ranges
TODO follow "Array" example
when Struct
TODO follow "Array" example
when OpenStruct
TODO follow "Array" example
when Enumerable
TODO follow "Array" example
else # fall back to the default inspect, and hope for the best
value.inspect
end
end