web-dev-qa-db-ja.com

scalaで補間して文字列に二重引用符を挿入する方法

関数内のすべての引用符をエスケープできない

(それの基本的な使用法->文字列が何もしない場合、文字列でない場合は、開始と終了に "を追加します)

コードスニペット :

  def putTheDoubleQuotes(value: Any): Any = {
    value match {
      case s: String => s //do something ...
      case _  => s"\"$value\"" //not working
    }
  }

働いたのは:

case _ => s "" "\" $ value\"" ""

これのためのより良い構文はありますか?

それはひどく見え、IDE(IntelliJ)はそれを赤でマークします(しかし、あなたは本当に私を怒らせます!!!!!)

43
Nimrod007

これはScalaのバグです。

エスケープは文字列補間では機能しません

しかし、多分あなたは使うことができます:

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
32
abzcoding

三重引用符で囲まれた文字列で引用符をエスケープする必要がないため、s""""$value""""" 働くでしょう。確かに、見た目も良くありません。

24
Alexey Romanov

別の解決策( Scala tracker にも記載されています)は、

case _ => s"${'"'}$value${'"'}"

まだいですが、トリプルクォートよりも好まれることもあります。

エスケープシーケンス$"は、2.12の SIP-24 の一部として提案されました。

case _ => s"$"$value$""

このSIPは、他のより議論の余地のある提案を含んでいたため、受け入れられませんでした。現在、エスケープシーケンス$" 2.13で Pre SIP/mini SIP $”補間でのエスケープ として実装されました。

18
Suma

ユースケースでは、ニース構文を簡単に実現できます。

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"

私に思い浮かんだもう1つのアイデアは、f補間器がすでに文字列をマッサージするための何らかの作業を行っているということです。たとえば、「%n」をインテリジェントに処理する必要があります。同時に、基礎となるフォーマッターに渡されない追加のエスケープ「%q」を処理できます。

次のようになります。

scala> f"%qhello, world%q"
<console>:9: error: conversions must follow a splice; use %% for literal %, %n for newline

それは機能強化の要求に値します。

更新:オクタルはまだ補間で非推奨ではないことに気付いた:

scala> s"\42hello, world\42"
res12: String = "hello, world"
8
som-snytt

これで問題が解決しました。これをテストしましたが、これが私が使用したものです。

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

http://docs.scala-lang.org/overviews/core/string-interpolation.html#the-raw-interpolator

7
NodeNodeNode

すでに述べたように、 これはScalaの既知のバグです 。回避策は、\042を使用することです。

5
fwc

どう?

s"This is ${"\"" + variable + "\""}" inserted in string with quotes

2
Naveen

私の場合は頻繁に使用されるため、このバージョンを作成しました。

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

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

簡単な方法:-

val str="abc"
println(s"$str") //without double quotes
println(s"""\"$str\"""") // with double quotes
2
Venu M

@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クラスのみを使用して、2つの拡張メソッドdqtおよびsqtを暗黙的に呼び出す中間オブジェクトを作成します。それでも、クラスをAnyValから継承することにより、このオブジェクトの作成を排除し、パフォーマンスを改善できます。 For Scalaは、コンパイラがメソッドを直接呼び出してオブジェクトを置換するような場合に特に値型を提供します。

これは、名前付き変数(文字列とブール値)と補間文字列の関数を使用する混合で上記の暗黙的なクラスを使用した簡単な例です。

import StringUtil._
abstract class Animal {
   ...
   override def toString(): String = s"Animal:${getFullName().dqt}, CanFly:$canFly, Sound:${getSound.dqt}"
 }
0
user-asterix