在Ruby中拆分多行上的长字符串而不删除换行符

chu*_*g2k 211 ruby ruby-on-rails

我们最近在工作中决定采用红宝石风格指南.其中一条规则是任何行都不应超过80个字符.由于这是一个Rails项目,我们经常会有一些更长的字符串 - 即" 用户X想要向您发送有关Thing Y的消息 ",这并不总是符合80个字符的样式限制.

我知道有三种方法可以让长字符串跨越多行:

  • HEREDOC
  • %Q {}
  • 实际字符串连接.

然而,所有这些情况最终都需要更多的计算周期,这看起来很愚蠢.字符串连接显然,但是HEREDOC,%Q我必须通过类似的方式删除换行符.gsub(/\n$/, '').

有没有纯语法方法来做到这一点,这相当于只需要将整个字符串放在一行上?显然,目标是不要花费任何额外的周期,因为我希望我的代码更具可读性.(是的,我意识到你必须做出很多权衡......但是对于字符串长度来说,这看起来很愚蠢.)

更新:反斜杠不是我想要的,因为你会丢失缩进,这实际上会影响样式/可读性.

例:

if foo
  string = "this is a \  
string that spans lines"  
end
Run Code Online (Sandbox Code Playgroud)

我发现上面有点难以阅读.

编辑:我在下面添加了一个答案; 三年后,我们现在有了波浪形的heredoc.

Jes*_*ehz 407

也许这就是你要找的东西?

string = "line #1"\
         "line #2"\
         "line #3"

p string # => "line #1line #2line #3"
Run Code Online (Sandbox Code Playgroud)

  • 我很确定它不是; 我尝试了undef'ing和重新定义String#+,似乎没有任何东西被发送到那里. (12认同)
  • 重新连接,查看Amadan对[此相关问题]的回答(http://stackoverflow.com/questions/27792508/ruby-backslash-to-continue-string-on-a-new-line).他使用字节码来证明它不是连接字符串,而是将它们视为一个长字符串. (5认同)
  • 呵呵.是的,那是非常完美的.实际上在引擎盖下连接?(隐藏一个+?) (4认同)
  • 我也喜欢Emily的解决方案.但由于某种原因,我对这个更舒服,因为在以下几行中引导的空格可以缩进而不用猜测自己. (3认同)

Emi*_*ily 52

您可以使用它\来指示任何Ruby行继续在下一行.这也适用于字符串:

string = "this is a \
string that spans lines"

puts string.inspect
Run Code Online (Sandbox Code Playgroud)

将输出 "this is a string that spans lines"

  • 呵呵.这很简单.好吧,问题可能太多了,但我不能缩进下一行.如果我能用等号匹配它是理想的. (11认同)
  • 注意:反斜杠后不能有空格.它必须是最后一个角色. (4认同)
  • 请参阅@Jessehz 的答案。使用适当缩进的格式良好的代码的方法是将每一行放在引号中。 (3认同)

chu*_*g2k 37

三年后,Ruby 2.3中出现了一个解决方案:波浪形的heredoc.

class Subscription
  def warning_message
    <<~HEREDOC
      Subscription expiring soon!
      Your free trial will expire in #{days_until_expiration} days.
      Please update your billing information.
    HEREDOC
  end
end
Run Code Online (Sandbox Code Playgroud)

博客文章链接:https://infinum.co/the-capsized-eight/articles/multiline-strings-ruby-2-3-0-the-squiggly-heredoc

最小缩进行的缩进将从内容的每一行中删除.

  • 对于其他任何想知道:"<< HEREDOC`保留换行符,它只是缩进的缩写.例如`第1行\nline 2 \nline 3 \n` (22认同)
  • 不过,剥离换行符仍然需要额外的计算,而 OP 所暗示的这种情况是不可取的。 (3认同)
  • @henrebotha是的,但OP更明确地说,他们希望“相当于将整个字符串放在一行上”,这不需要换行符。 (2认同)
  • 因此,您在问题中明确指出您不想使用heredoc并且必须删除换行符。您在这里的答案使用了heredoc,并且需要您想要避免的“后处理”。 (2认同)

小智 26

这是一个非常老的问题,但由于这个问题似乎仍然出现,这里有一个更新的答案。由于原始海报表明这是针对 Rails 项目的,因此您可以向 Rails 的字符串变形寻求帮助。

my_long_string = <<-STRING
 hello
    there
 multiline
      multiindented string
STRING

=> " hello\n    there\n multiline\n      multiindented string\n"
Run Code Online (Sandbox Code Playgroud)

输入squish方法。

my_long_string = <<-STRING.squish
 so
    long
 multiline
      multiindented string
STRING

=> "so long multiline multiindented string"
Run Code Online (Sandbox Code Playgroud)

根据文档 -

squish() 返回字符串,首先删除字符串两端的所有空格,然后将剩余的连续空格组各改为一个空格。

  • 就是这样。 (3认同)

Zac*_* Xu 17

当我尝试写一个很长的URL时,我遇到了这个问题,以下是有效的.

image_url = %w(
    http://minio.127.0.0.1.xip.io:9000/
    bucket29/docs/b7cfab0e-0119-452c-b262-1b78e3fccf38/
    28ed3774-b234-4de2-9a11-7d657707f79c?
    X-Amz-Algorithm=AWS4-HMAC-SHA256&
    X-Amz-Credential=ABABABABABABABABA
    %2Fus-east-1%2Fs3%2Faws4_request&
    X-Amz-Date=20170702T000940Z&
    X-Amz-Expires=3600&X-Amz-SignedHeaders=host&
    X-Amz-Signature=ABABABABABABABABABABAB
    ABABABABABABABABABABABABABABABABABABA
).join
Run Code Online (Sandbox Code Playgroud)

注意,在形成url字符串时,一定不能有任何换行符,空格.如果您想要换行,请使用HEREDOC.

在这里你有缩进的可读性,易于修改,没有每行的繁琐的引号和反斜杠.加入琴弦的成本应该可以忽略不计.


ihe*_*gie 9

我修改了Zack的答案,因为我想要空格和插值而不是新行并使用:

%W[
  It's a nice day "#{name}"
  for a walk!
].join(' ')
Run Code Online (Sandbox Code Playgroud)

其中,name = 'fred'这将产生It's a nice day "fred" for a walk!