没有缩进的多行字符串

时间:2015-11-04 16:29:47

标签: ruby multilinestring

如何使用没有前导空格且仍与方法正确对齐的多行字符串?以下是我的一些尝试。工作的那个不是很有趣......

module Something
  def welcome
"
Hello

This is an example.  I have to write this multiline string outside the welcome method
indentation in order for it to be properly formatted on screen. :(
"
  end
end

module Something
  def welcome
    "
    Hello

    This is an example.  I am inside welcome method indentation but for some reason
    I am not working...
    ".ljust(12)
  end
end

module Something
  def welcome
    "Hello\n\n"+
    "This is an example.  I am inside welcome method indentation and properly"+
    "formatted but isn't there a better way?"
  end
end

更新

这是method from the ruby style guide

code = <<-END.gsub(/^\s+\|/, '')
  |def test
  |  some_method
  |  other_method
  |end
END
# => "def test\n  some_method\n  other_method\nend\n"

4 个答案:

答案 0 :(得分:20)

从Ruby 2.3.0开始,有一个内置的方法:[<<~]

indented = 
<<-EOS
  Hello

  This is an example. I have to write this multiline string outside the welcome method indentation in order for it to be properly formatted on screen. :(
EOS

unindented =
<<~EOS
  Hello

  This is an example. I have to write this multiline string outside the welcome method indentation in order for it to be properly formatted on screen. :(
EOS

puts indented #=>

  Hello

  This is an example. I have to write this multiline string outside the welcome method indentation in order for it to be properly formatted on screen. :(

puts unindented #=>

Hello

This is an example. I have to write this multiline string outside the welcome method indentation in order for it to be properly formatted on screen. :(

Multiline strings in Ruby 2.3 - the squiggly heredoc

答案 1 :(得分:3)

RubyTapas Episode 249中,Avdi Grimm描述了一种从多行字符串中去除前导空格的技术:

def unindent(s)
  s.gsub(/^#{s.scan(/^[ \t]+(?=\S)/).min}/, '')
end

与此问题的其他现有解决方案兼容的行为,例如, ActiveSupport / Rails中的String#strip_heredoc或独立的unindent gem

您可以将此方法与heredoc一起使用,这是ruby(和许多其他语言)中的特殊语法来编写多行字符串。

module Something
  def unindent(s)
    s.gsub(/^#{s.scan(/^[ \t]+(?=\S)/).min}/, '')
  end

  def welcome
    unindent(<<-TEXT)
      Hello

      This is an example. This multiline string works
        - even with deeper nestings...
      All is OK here :)
    TEXT
  end
end

答案 2 :(得分:2)

您可以使用HEREDOC - http://ruby-doc.org/docs/ruby-doc-bundle/Manual/man-1.4/syntax.html#here_doc - 就像这样:

def welcome
  <<-"welcome".strip_heredoc
    "
    Hello

    This is an example.  I have to write this multiline string outside the welcome method indentation in order for it to be properly formatted on screen. :(
    "
  welcome
end

并使用strip_heredoc删除缩进 - http://apidock.com/rails/String/strip_heredoc

注意:

strip_heredoc仅在您使用Ruby on Rails(它是Rails助手)时才可用。如果你只是用纯Ruby构建它,遗憾的是strip_heredoc将无法使用strip_heredoc。 : - (

但是害怕不是纯粹的Ruby用户!您只需从Rails中提取String的源代码,然后通过重新定义class String def strip_it_real_good indent = scan(/^[ \t]*(?=\S)/).min.try(:size) || 0 gsub(/^[ \t]{#{indent}}/, '') end end def welcome <<-"welcome".strip_it_real_good " Hello This is an example. I have to write this multiline string outside the welcome method indentation in order for it to be properly formatted on screen. :( " welcome end 类将其添加到Ruby。在这种情况下,您也可以随意调用该方法。 : - )

像这样:

{{1}}

答案 3 :(得分:0)

我不确定我理解这个问题。这个(纯Ruby)解决方案能满足您的需求吗?

arr = <<-BITTER_END.split("\n")
  Hello
         Testing, testing.
       I assume the least-indented line is to be left-adjusted and the same amount of leading whitespace is to be removed from all other lines.
BITTER_END
undent = arr.map { |line| line[/^\s*/].size }.min
str = arr.map { |s| s[undent..-1] }.join("\n")

puts str
Hello
     Testing, testing.
   I assume the least-indented line is to be left-adjusted and the same amount of leading whitespace is to be removed from all other lines.