6

简而言之:

"""I want to be able to
  |have the convenient formatting of a multiline string,
  |while using inline escape sequences\r\r\b\\
  |
  |How can this be done?""".stripMargin
4

3 回答 3

13

我能想到的两个选择:

  1. 你可以StringContext.treatEscapes直接使用:

    StringContext.treatEscapes("""I want to be able to
            |have the convenient formatting of a multiline string,
            |while using inline escape sequences\r\r\b\\
            |
            |How can this be done?""".stripMargin)
    
  2. 如果“简单插值器”( s) 的变量替换功能不会破坏您的需求,请尝试将字符串插值(转换转义字符)与"""-quotes(不转义......)结合起来:

    println("""he\\lo\nworld""")
    println(s"""he\\lo\nworld""")
    

    输出

    he\\lo\nworld
    he\lo
    world
    

    有关详细信息,请参阅相关 SIP这个较早的问题

于 2013-07-25T21:28:28.270 回答
3

除了其他答案 - 这个想法怎么样?

s"""I want to be able to
  |have the convenient formatting of a multiline string,
  |while using inline escape sequences${"\r\r\b\"}\
  |
  |How can this be done?""".stripMargin

唯一不能以这种方式工作\的是行尾。在我的示例中,您将转义字符嵌入为普通字符串,然后使用字符串插值插入它们。(注意s开头的三引号。)

于 2013-07-26T13:25:26.447 回答
2

标准库中隐藏了一个方便的示例。可以通过多种方式轻松调整以添加标准处理。然而,嵌入式\r的意图并不明显,因此caveat interpolator.

更新:为了记录,困难的部分是忘记序列 arg _*。因为是 Any*,所以没有类型错误;底层插值器只是抛出一个错误,即部分与 args 不匹配。

更新:固定下划线星号,使其不斜体。

例子:

import reflect.internal.util.StripMarginInterpolator

object Test extends App {

  trait ZipMarginator extends StripMarginInterpolator {
    def zm(args: Any*): String = StringContext treatEscapes sm(args: _*)
  }
  implicit class ZipMarginOps(val stringContext: StringContext) extends ZipMarginator
  val sample =
zm"""I want to be able to
    |have the convenient formatting of a multiline string,
    |while using inline escape sequences
    |like\t\ttabs and \\Program Files\\backslashes.
    |
    |How can this be done?"""
  Console println sample

  implicit class ZipMarginOps2(val stringContext: StringContext) extends SStripMarginInterpolator {
    def sz(args: Any*): String = ssm(args: _*)
  }
  Console println sz"""
    |Another\t\texample."""
  Console println sz"""
    |Another\r\tex\nample.
    |Huh?"""

}

这是 StripMargin..或更改名称以保护一个人的理智,请注意有关以下内容的警告raw

trait SStripMarginInterpolator {
  def stringContext: StringContext

  /**
   * A safe combination of [[scala.collection.immutable.StringLike#stripMargin]]
   * and [[scala.StringContext#raw]].
   *
   * The margin of each line is defined by whitespace leading up to a '|' character.
   * This margin is stripped '''before''' the arguments are interpolated into to string.
   *
   * String escape sequences are '''not''' processed; this interpolater is designed to
   * be used with triple quoted Strings.
   *
   * {{{
   * scala> val foo = "f|o|o"
   * foo: String = f|o|o
   * scala> sm"""|${foo}
   *             |"""
   * res0: String =
   * "f|o|o
   * "
   * }}}
   */
  final def ssm(args: Any*): String = {
    def isLineBreak(c: Char) = c == '\n' || c == '\f' // compatible with StringLike#isLineBreak
    def stripTrailingPart(s: String) = {
      val (pre, post) = s.span(c => !isLineBreak(c))
      pre + post.stripMargin
    }
    val stripped: List[String] = stringContext.parts.toList match {
      case head :: tail => head.stripMargin :: (tail map stripTrailingPart)
      case Nil => Nil
    }
    new StringContext(stripped: _*).s(args: _*)  // <= MODIFIED for s instead of raw
  }
}
于 2013-07-26T01:04:20.513 回答