如何在scala中使用插值将双引号插入字符串

如何在scala中使用插值将双引号插入字符串,scala,intellij-idea,Scala,Intellij Idea,无法转义函数中的所有引号 (它的基本用法->如果我发现一个字符串,则什么也不做,如果它不是字符串,则在开始和结束处添加) 代码段: def putTheDoubleQuotes(value: Any): Any = { value match { case s: String => s //do something ... case _ => s"\"$value\"" //not working } } 唯一有效的办法是: 大小写

无法转义函数中的所有引号

(它的基本用法->如果我发现一个字符串,则什么也不做,如果它不是字符串,则在开始和结束处添加)

代码段:

  def putTheDoubleQuotes(value: Any): Any = {
    value match {
      case s: String => s //do something ...
      case _  => s"\"$value\"" //not working
    }
  }
唯一有效的办法是:

大小写=s“\$value”

有更好的语法吗


它看起来很糟糕,IDE(IntelliJ)将其标记为红色(但让您运行它,这真的让我很恼火!!!)

这是Scala中的一个bug:

但也许你可以使用:

scala> import org.apache.commons.lang.StringEscapeUtils.escapeJava
import org.apache.commons.lang.StringEscapeUtils.escapeJava

scala> escapeJava("this is a string\nover two lines")
res1: java.lang.String = this is a string\nover two lines

您不需要在三重引号字符串中转义引号,因此
s''$value''
将起作用。诚然,它看起来也不太好。

对于您的用例,它们使实现良好语法变得容易

scala> implicit class `string quoter`(val sc: StringContext) {
     | def q(args: Any*): String = "\"" + sc.s(args: _*) + "\""
     | }
defined class string$u0020quoter

scala> q"hello,${" "*8}world"
res0: String = "hello,        world"

scala> "hello, world"
res1: String = hello, world       // REPL doesn't add the quotes, sanity check

scala> " hello, world "
res2: String = " hello, world "   // unless the string is untrimmed
将隐式存储在某个包对象中

当然,除了
q
,您还可以给插值器命名

上周,有人在ML上询问使用反向引用标识符的能力。现在您可以执行res3,但不能执行res4:

scala> val `"` = "\""
": String = "

scala> s"${`"`}"
res3: String = "

scala> s"hello, so-called $`"`world$`"`"
res4: String = hello, so-called "world"
我刚刚想到的另一个想法是,f插值器已经做了一些工作来按摩你的字符串。例如,它必须智能地处理“%n”。同时,它可以处理一个额外的转义“%q”,该转义不会传递给底层格式化程序

这看起来像:

scala> f"%qhello, world%q"
<console>:9: error: conversions must follow a splice; use %% for literal %, %n for newline
另一个解决方案(在中也提到)是使用

case _ => s"${'"'}$value${'"'}"
仍然难看,但有时可能比三重报价更受欢迎

似乎有人建议将转义序列
$”
作为for 2.12的一部分:

case _ => s"$"$value$""
此SIP从未被接受,因为它包含其他更具争议性的建议。目前正在努力在2.13 as中实现转义序列
$”

如何


s“这是插入带引号的字符串中的${“\”“+variable+“\”“}”

这为我解决了问题,我对此进行了测试,这就是我使用的

raw""" 
   Inside this block you can put "as many" quotes as you "want" and even "${5 + 7}" interpolate inside the quotes 
"""

如前所述。解决方法是使用
\042

在我的案例中大量使用,因此我创建了以下版本:

object StringUtil{
    implicit class StringImprovements(s: String) {
        def quoted = "\""+s+"\""
    }
}

val myStatement = s"INSERT INTO ${tableName.quoted} ..."

进一步采取@Pascalius建议。类StringImprovements扩展并继承AnyVal

object StringUtil{
    implicit class StringImprovements(val s: String) extends AnyVal {
        def dqt = "\""+s+"\""    // double quote
        def sqt = s"'$s'"        // single quote
    }
}
Scala只使用StringImprovements类创建一个中间对象,在该对象上隐式调用两个扩展方法dqt和sqt。然而,我们可以通过使类从AnyVal继承来消除此对象的创建并提高性能。For Scala专门为以下情况提供了值类型:编译器将通过直接调用方法来替换对象

下面是一个简单的示例,在混合中使用上述隐式类,其中使用命名变量(string&boolean)和插值字符串中的函数

import StringUtil._
abstract class Animal {
   ...
   override def toString(): String = s"Animal:${getFullName().dqt}, CanFly:$canFly, Sound:${getSound.dqt}"
 }
简单方法:

val str="abc"
println(s"$str") //without double quotes
println(s"""\"$str\"""") // with double quotes
例如:

scala> val username="admin"
> username: String = admin

scala> val pass="xyz"
> pass: String = xyz

scala> println(s"""{"username":"$username", "pass":"$pass"}""")
> {"username":"admin", "pass":"xyz"}

启动Scala 2.13.6时,按照字符串插值中的预期对双引号进行了转义

Welcome to Scala 2.13.6 (OpenJDK 64-Bit Server VM, Java 15.0.2).
Type in expressions for evaluation. Or try :help.

scala> s"\"Hello\""
val res0: String = "Hello"

scala> s"$"Hello$""
val res1: String = "Hello"

这个:s“\”$value\”在命令行中不起作用(不仅仅是在IDE中),也许我应该换一句话:escape在Scala中不适用于字符串插值,因此在intellij中,尽管您说这是intellij报告的错误。。。不管怎样,我正在寻找好的语法,而escapeJava很烦人,也许这会有所帮助:有一个PR,但仍在悬而未决的提案中。如何
s“”$value“”“.trim
?:)另一个答案建议使用额外的反斜杠来抵消字面上的引用,这是一种不错的风格。您可以想象scalafix或scalafmt强制执行它。使用s作为前缀,三个引号来开始字符串,省略反斜杠,对我来说这是一个很酷的解决方法!使用三重引号时,不需要反斜杠现在
不支持八进制转义文字:改为使用\u0022
。反斜杠不是必需的,但在视觉上很好。请参阅三重引号的另一个答案。与其他解决方案相比,这太冗长了。@som snytt-我同意你的看法,太冗长了。这只是其他选择中的一种:):::)是最小的SO响应这篇文章至少需要一些更有用的格式(),以便可读性足以被视为答案。理想情况下,添加一些解释,这会增加帮助,也有助于消除StackOverflow是免费编程服务的误解。这个答案是误导性的。它使用原始内插器和三重引号字符串,允许使用未转换的引号。本例中没有任何东西需要原始插值器。
Welcome to Scala 2.13.6 (OpenJDK 64-Bit Server VM, Java 15.0.2).
Type in expressions for evaluation. Or try :help.

scala> s"\"Hello\""
val res0: String = "Hello"

scala> s"$"Hello$""
val res1: String = "Hello"