web-dev-qa-db-fra.com

Comment insérer des guillemets doubles dans String avec interpolation dans scala

Ayant du mal à échapper à toutes les citations dans ma fonction

(utilisation de base de celui-ci -> si je trouve une chaîne, ne faites rien, si ce n'est pas une chaîne, ajoutez "au début et à la fin)

extrait de code :

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

la seule chose qui a fonctionné était:

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

existe-t-il une meilleure syntaxe pour cela?

il a l'air terrible et le IDE (IntelliJ) le marque en rouge (mais vous permet de l'exécuter ce qui me fait vraiment chier !!!!!))

43
Nimrod007

C'est un bug dans Scala:

l'échappement ne fonctionne pas avec l'interpolation de chaînes

mais vous pouvez peut-être utiliser:

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

Vous n'avez pas besoin d'échapper les guillemets dans une chaîne entre guillemets, donc s""""$value""""" marchera. Certes, ça n'a pas l'air bien non plus.

24
Alexey Romanov

Une autre solution (également mentionnée dans le Scala tracker ) consiste à utiliser

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

Toujours moche, mais parfois peut-être préférable aux triples guillemets.

Il semble qu'une séquence d'échappement $" a été suggéré dans le cadre de SIP-24 pour 2.12:

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

Ce SIP n'a jamais été accepté, car il contenait d'autres suggestions plus controversées. Actuellement, il y a un effort pour obtenir la séquence d'échappement $" implémenté en 2.13 comme Pre SIP/mini SIP $ ”s'échappe dans les interpolations .

18
Suma

Pour votre cas d'utilisation, ils facilitent la réalisation de la syntaxe Nice.

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

Écurinez quelque part l'implicite dans un objet package.

Vous pouvez nommer l'interpolateur autre chose que q, bien sûr.

La semaine dernière, quelqu'un a demandé sur le ML la possibilité d'utiliser des identifiants rétro-cotés. En ce moment, vous pouvez faire res3 mais pas res4:

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

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

scala> s"hello, so-called $`"`world$`"`"
res4: String = hello, so-called "world"

Une autre idée qui m'est venue à l'esprit est que l'interpolateur f fait déjà un peu de travail pour masser votre corde. Par exemple, il doit gérer "% n" intelligemment. Il pourrait, en même temps, gérer un échappement supplémentaire "% q" qu'il ne passerait pas au formateur sous-jacent.

Cela ressemblerait à:

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

Cela vaut une demande d'amélioration.

Mise à jour: vient de remarquer que les octales ne sont pas encore obsolètes dans les interpolations:

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

Cela a résolu le problème pour moi, j'ai testé cela et c'est ce que j'ai utilisé.

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

Comme déjà mentionné, c'est un bogue connu dans Scala . Une solution de contournement consiste à utiliser \042.

5
fwc

Que diriez-vous

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

2
Naveen

Il est très utilisé dans mon cas, j'ai donc créé cette version:

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

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

Manière simple: -

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

Prenant la suggestion @Pascalius un peu plus loin. La classe StringImprovements étend et hérite d'AnyVal.

object StringUtil{
    implicit class StringImprovements(val s: String) extends AnyVal {
        def dqt = "\""+s+"\""    // double quote
        def sqt = s"'$s'"        // single quote
    }
}

Scala utilise uniquement la classe StringImprovements pour créer un objet intermédiaire sur lequel appeler implicitement les deux méthodes d'extension dqt & sqt. Néanmoins, nous pouvons éliminer la création de cet objet et améliorer les performances en faisant hériter la classe d'AnyVal. Pour Scala fournit le type de valeur spécifiquement pour les cas où le compilateur remplacera l'objet simplement en appelant directement la méthode.

Voici un exemple simple utilisant la classe implicite ci-dessus dans un mélange où nous utilisons des variables nommées (chaîne et booléenne) et une fonction dans la chaîne d'interpolation.

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