【问题标题】:Strange bug with string interpolation字符串插值的奇怪错误
【发布时间】:2014-03-28 13:53:19
【问题描述】:

以下代码出现一个奇怪的错误。

我有一个类Example,带有一个伴随对象,我在其中定义了一个字符串SIGN。在Example 类中,我有一个创建正则表达式的方法,并使用字符串插值,这样我就可以使用SIGN 来构建我的正则表达式。

这可以编译,但我在运行时遇到一个奇怪的错误。这是一个 Scala 错误吗?我正在使用 Scala 2.10.3(在 Windows 7 上)。

scala> :paste
// Entering paste mode (ctrl-D to finish)

class Example {
  import Example._
  def regex = s"""$SIGN?\d+""".r
}

object Example {
  private val SIGN = """(\+|-)"""
}


// Exiting paste mode, now interpreting.

defined class Example
defined module Example

scala> val e = new Example
e: Example = Example@77c957d9

scala> e.regex
scala.StringContext$InvalidEscapeException: invalid escape character at index 1 in "?\d+"
        at scala.StringContext$.treatEscapes(StringContext.scala:229)
        at scala.StringContext$$anonfun$s$1.apply(StringContext.scala:90)
        at scala.StringContext$$anonfun$s$1.apply(StringContext.scala:90)
        at scala.StringContext.standardInterpolator(StringContext.scala:123)
        at scala.StringContext.s(StringContext.scala:90)
        at Example.regex(<console>:9)

【问题讨论】:

  • @raina77ow 这也不起作用,我得到了同样的异常。
  • 看起来您看到的是this issue 的某个版本,也许吧?普通的旧 s"$SIGN?\\d+".r 应该可以正常工作。
  • 是的,它适用于`\\`。
  • @TravisBrown 请提交您的评论作为答案,然后我会接受它作为我问题的答案。
  • 你要的是r"""$SIGN?\d+"""

标签: regex scala string-interpolation


【解决方案1】:

仔细查看堆栈跟踪后,我知道发生了什么。

可以看到s方法在字符串上执行,处理$SIGN的替换。该方法在字符串中遇到\d,显然试图翻译它;在堆栈跟踪中查看对treatEscapes 的调用。 treatEscapes 方法无法识别 \d 并引发异常。

可以通过在字符串中写入\\d 来修复它,但这违背了使用三引号字符串的全部目的...

结论:字符串插值和三引号字符串似乎相互干扰。我会说这是一个 Scala 错误。 (为什么s 方法会处理转义?)。

edit - 正如 Travis Brown 在评论中指出的那样,这确实看起来像错误 SI-6476

【讨论】:

  • 向 Scala 项目提交更好的错误消息会很高兴(只花了 1 小时才找到这个愚蠢的小错误)。该消息将提供解决方法,而不是有史以来最好的方法,但会有所帮助...
  • 代码正在被触及,所以现在是提出建议的好时机。但是很难猜测解决方法。也许是显示正常字符串转义的详细模式。 github.com/scala/scala/pull/3695
  • @pommedeterresautee 查看我的上一条评论。此外,SI-6476 是相反的问题,人们抱怨普通 s"" 不支持转义引号。我猜你想逃避真正基本的东西,s"""$a\n$b"""。 Odersky 表示,尽管他对此表示怀疑,但该功能是多么明显的胜利,但人们对各种边缘情况感到厌烦。
  • @pommedeterresautee 我将 8 个 esc 字符添加到我的 PR 中的 msg 中。我会尝试添加 s.t.就像“使用 \\ 表示文字 \”。 f"%" 也有类似的变化,改为 "use %% for literal %"。
  • @pommedeterresautee 刚刚意识到f"a\" 说:error: Trailing '\' escapes nothing. 几个月前我在 f 中添加了这种扩展检查。
猜你喜欢
  • 1970-01-01
  • 2016-05-09
  • 1970-01-01
  • 1970-01-01
  • 2021-10-24
  • 1970-01-01
  • 1970-01-01
  • 2020-08-03
  • 1970-01-01
相关资源
最近更新 更多