如果字符串开头和结尾都有引号,如何从字符串中去除它们?

3
如何仅在字符串开头和结尾都有引号时,从字符串中删除这些引号?例如:
"hello world" => hello world
"hello world => "hello world
hello world" => hello world"

我使用了gsub,但是下面的代码会移除每个字符串开头或结尾的引号,无论另一个引号是否存在。
'"hello world"'.gsub(/\A"|"\Z/, '')
# => this is ok it returns 'hello world'

'hello world"'.gsub(/\A"|"\Z/, '')
# => returns 'hello world' but should return 'hello world"'

虽然不是重复的问题,但是https://dev59.com/IHA75IYBdhLWcg3wJFcL非常接近并且会给你一些想法。 - the Tin Man
4个回答

3

您可以使用

str.gsub(/\A"+(.*?)"+\Z/m, '\1')

该模式将匹配以一个或多个"开头的字符串,然后可以有任何字符、任意数量的字符,最后以一个或多个双引号结束。整个字符串(不包括前导和尾随引号)将插入替换结果中,并使用\1反向引用。

请参见IDEONE演示

要仅修剪第一个和最后一个双引号,您可以使用

str.gsub(/\A"(.*)"\Z/m, '\1')

1
如果“+”后面跟着一个贪婪匹配符“(.*)”,那么“+”不是无用的吗?请参见:https://ideone.com/Ucu39f 我非常确定您想使用懒惰量词/\A"+(.*?)"+\Z/ - Josh Crozier
已点赞,但我认为您不需要在末尾使用s修饰符。在Ruby中,s修饰符表示正则表达式的编码是Windows-31J(文档)。 - Jordan Running
@JoshCrozier:没错,你说得对。我很匆忙,忘记了这一点。 - Wiktor Stribiżew
如果我只想删除开头和结尾的一个引号,会是什么样子? - 23tux
@23tux:只需删除+即可。此外,您可能需要检查字符串的末尾,并使用\z而不是\Z。使用.gsub(/\A"(.*)"\Z/m, '\1').gsub(/\A"(.*)"\z/m, '\1')(已更新答案)。 - Wiktor Stribiżew

2
我认为这样比使用正则表达式更有效率。
'"hello world'
.dup.tap{|s| s[0] = s[-1] = "" if s[0] == '"' and s[-1] == '"'}
# => "\"hello world"
'"hello world"'
.dup.tap{|s| s[0] = s[-1] = "" if s[0] == '"' and s[-1] == '"'}
# => "hello world"
'hello world"'
.dup.tap{|s| s[0] = s[-1] = "" if s[0] == '"' and s[-1] == '"'}
# => "hello world\""

我更喜欢 gsub 的解决方案,但因为你说得对这个更快,所以我点了赞:https://gist.github.com/jrunning/a5f814c9a880960d0139 - Jordan Running

2

使用Ruby的好处是,在许多情况下,您可以编写看起来像英语的代码。它的好处是易于理解。

x = '"hello world"'
quote = '"'

if x.start_with?(quote) && x.end_with?(quote)
  x = x[1...-1] 
end

puts x #=> hello world 

1

我不会费心使用正则表达式:

def strip_end_quotes(str)
  str[0] == '"' && str[-1] == '"' \
    ? str[1..-2] \
    : str
end

strip_end_quotes '"both"' # => "both"
strip_end_quotes '"left' # => "\"left"
strip_end_quotes 'right"' # => "right\""

在编程中,清晰易懂非常重要,因此将其转换为单个正则表达式会导致模式不太清晰。对于未来需要维护代码的人来说,保持可读性是很好的做法。

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