【发布时间】:2010-08-10 20:43:16
【问题描述】:
我想在 Ruby 中从字符串中去除前导引号和尾随引号。引号字符将出现 0 或 1 次。例如,以下所有内容都应转换为 foo,bar:
"foo,bar""foo,barfoo,bar"foo,bar
【问题讨论】:
-
"How to Ask" 和 "minimal reproducible example" 很好读。
我想在 Ruby 中从字符串中去除前导引号和尾随引号。引号字符将出现 0 或 1 次。例如,以下所有内容都应转换为 foo,bar:
"foo,bar""foo,barfoo,bar"foo,bar【问题讨论】:
您也可以使用chomp 函数,但不幸的是,它只适用于字符串的末尾,假设有一个反向 chomp,您可以:
'"foo,bar"'.rchomp('"').chomp('"')
实现rchomp 很简单:
class String
def rchomp(sep = $/)
self.start_with?(sep) ? self[sep.size..-1] : self
end
end
请注意,您也可以使用效率稍低的版本进行内联:
'"foo,bar"'.chomp('"').reverse.chomp('"').reverse
编辑:从 Ruby 2.5 开始,rchomp(x) 可以在名称 delete_prefix 下使用,chomp(x) 可以在 delete_suffix 下使用,这意味着您可以使用
'"foo,bar"'.delete_prefix('"').delete_suffix('"')
【讨论】:
delete_suffix 和 delete_prefix 方法在那里,也许在写这个答案时它们不存在
我可以使用 gsub 搜索前导或尾随引号并将其替换为空字符串:
s = "\"foo,bar\""
s.gsub!(/^\"|\"?$/, '')
正如下面 cmets 所建议的,更好的解决方案是:
s.gsub!(/\A"|"\Z/, '')
【讨论】:
Regexp 中的引号,因为引号在Regexp 中没有任何特殊含义。此外,^ 和 $ 不 锚定到 string 的开头和结尾,它们锚定到 line 的开头和结尾我>。从你的问题中不清楚你想要哪一个:如果你想从字符串的开头和结尾删除引号,你需要使用 \A 和 \Z 代替。最后,您可以通过用单引号分隔字符串来摆脱双引号的转义(以及令人困惑的双引号)。
s.gsub!(/\A"|"\Z/, '')吗?
像往常一样,每个人都会先从工具箱中获取正则表达式。 :-)
作为替代方案,我建议您查看.tr('"', '')(又名“翻译”),在这种用法中,它实际上是在去除引号。
【讨论】:
"。
另一种方法是
remove_quotations('"foo,bar"')
def remove_quotations(str)
if str.start_with?('"')
str = str.slice(1..-1)
end
if str.end_with?('"')
str = str.slice(0..-2)
end
end
它没有 RegExps 和 start_with?/end_with?可读性很好。
【讨论】:
让我感到沮丧的是 strip 只适用于空白。我需要剥离各种字符!这是一个可以解决这个问题的字符串扩展:
class String
def trim sep=/\s/
sep_source = sep.is_a?(Regexp) ? sep.source : Regexp.escape(sep)
pattern = Regexp.new("\\A(#{sep_source})*(.*?)(#{sep_source})*\\z")
self[pattern, 2]
end
end
输出
'"foo,bar"'.trim '"' # => "foo,bar"
'"foo,bar'.trim '"' # => "foo,bar"
'foo,bar"'.trim '"' # => "foo,bar"
'foo,bar'.trim '"' # => "foo,bar"
' foo,bar'.trim # => "foo,bar"
'afoo,bare'.trim /[aeiou]/ # => "foo,bar"
【讨论】:
假设引号只能出现在开头或结尾,您可以删除所有引号,无需任何自定义方法:
'"foo,bar"'.delete('"')
【讨论】:
我想要相同的,但对于 url 路径中的斜杠,它可以是 /test/test/test/(因此它在中间有剥离字符)并最终想出了这样的东西来避免正则表达式:
'/test/test/test/'.split('/').reject(|i| i.empty?).join('/')
在这种情况下显然可以转换为:
'"foo,bar"'.split('"').select{|i| i != ""}.join('"')
或
'"foo,bar"'.split('"').reject{|i| i.empty?}.join('"')
【讨论】:
正则表达式可能非常繁重并导致一些时髦的错误。如果您不处理大量字符串并且数据非常统一,则可以使用更简单的方法。
如果你知道字符串有开头和前导引号,你可以拼接整个字符串:
string = "'This has quotes!'"
trimmed = string[1..-2]
puts trimmed # "This has quotes!"
这也可以变成一个简单的函数:
# In this case, 34 is \" and 39 is ', you can add other codes etc.
def trim_chars(string, char_codes=[34, 39])
if char_codes.include?(string[0]) && char_codes.include?(string[-1])
string[1..-2]
else
string
end
end
【讨论】:
您可以使用scan 去除非可选引号:
'"foo"bar"'.scan(/"(.*)"/)[0][0]
# => "foo\"bar"
【讨论】: