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

时间:2012-05-09 18:58:10

标签: ruby-on-rails ruby

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

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

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

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

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

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

示例:

if foo
  string = "this is a \  
string that spans lines"  
end

我觉得上面的内容有点难以阅读。

  

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

7 个答案:

答案 0 :(得分:375)

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

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

p string # => "line #1line #2line #3"

答案 1 :(得分:49)

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

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

puts string.inspect

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

答案 2 :(得分:34)

三年后,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

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

  

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

答案 3 :(得分:14)

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

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

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

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

答案 4 :(得分:7)

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

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

name = 'fred'这会产生It's a nice day "fred" for a walk!

答案 5 :(得分:2)

这是一个非常古老的问题,但由于问题似乎仍然存在,这里是一个更新的答案。由于原始海报表明这是针对 Rails 项目的,因此您可以查看 Rails 的 String inflections 寻求帮助。

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

=> " hello\n    there\n multiline\n      multiindented string\n"

输入 squish 方法。

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

=> "so long multiline multiindented string"

根据文档 -

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

答案 6 :(得分:0)

您可以连接拆分为多行的多个字符串:

import jmespath

df = jmespath.search("""{name:[].name, 
                         age: [].age, 
                         street: [].address.street, 
                         city: [].address.city}
                     """, 
                     json_data)

pd.DataFrame(df)
 
         name age        street      city
0  Brad Green  35  Nicol St. 16  Manhatan
1  Sara Brown  30   Adam St. 66  New York