En Java, ¿hay alguna forma de escribir una cadena literal sin tener que escapar de las comillas?

111

Supongamos que tiene un literal String con muchas comillas en su interior. Podrías escapar de todos ellos, pero es un fastidio y difícil de leer.

En algunos idiomas, puedes hacer esto:

foo = '"Hello, World"';

En Java, sin embargo, ''se usa para chars, por lo que no puede usarlo para Strings de esta manera. Algunos lenguajes tienen sintaxis para solucionar este problema. Por ejemplo, en Python, puede hacer esto:

"""A pretty "convenient" string"""

¿Java tiene algo similar?

Mateo
fuente
Relacionado: stackoverflow.com/questions/2678483/…
Michael Mrozek
Esta respuesta muestra cómo pegar cadenas de escape de varias líneas en Eclispe.
Jeff Axelrod
2
Actualización 2018: podrían llegar literales de cadena sin formato para Java. Vea mi respuesta a continuación
VonC
importar jackson ObjectMapper luego System.out.println(mapperObj.writeValueAsString(mapperObj.readValue(str, Object.class)));
Kervvv
actualización del cuarto trimestre de 2018: el literal de cadena sin formato aún no está disponible. Vea mi respuesta actualizada .
VonC

Respuestas:

74

La respuesta es no, y la prueba reside en la Especificación del lenguaje Java :

  StringLiteral:
   "StringCharacters"

  StringCharacters:
   StringCharacter
   | StringCharacters StringCharacter

  StringCharacter:
   InputCharacter but not " or \
   | EscapeSequence

Como puede ver, un StringLiteralsolo puede estar limitado "y no puede contener un carácter especial sin escapes.

Una nota al margen: puedes incrustar Groovy dentro de tu proyecto, esto extenderá la sintaxis de Java permitiéndote usar '''multi line string ''', ' "string with single quotes" 'y también "string with ${variable}".

Jack
fuente
141

No, y siempre me ha molestado la falta de diferentes sintaxis de cadena literal en Java.

Aquí hay un truco que he usado de vez en cuando:

String myString = "using `backticks` instead of quotes".replace('`', '"');

Principalmente solo hago algo así para un campo estático. Dado que es estático, el código de reemplazo de cadena se llama una vez, al inicializar la clase. Por tanto, la penalización del rendimiento en tiempo de ejecución es prácticamente inexistente y hace que el código sea considerablemente más legible.

benjismith
fuente
¿No necesitarías usar replaceAll?
Landon Kuhn
10
@ landon9720 No, .replace reemplaza todas las apariciones de una secuencia de carácter / carácter con otra secuencia de carácter / carácter. .replaceAll usa expresiones regulares.
abelito
Por curiosidad, ¿sabe si el compilador java simplificaría esto al compilar?
ug_
2
No, no creo que el compilador simplificaría esto. Pero realmente no importa. Es una llamada muy económica, y si solo hago esto para cadenas finales estáticas, solo se incurrirá en el costo una vez, al cargar la clase. Ese es un precio que generalmente estoy dispuesto a pagar por un código de mejor apariencia :)
benjismith
3
Entonces, ¿qué pasa con "\" en myString?
Anderson
10

Actualización de diciembre de 2018 (12 meses después):

Los literales de cadena sin formato (que están en la lista ámbar ) no llegarán al JDK 12.
Vea las críticas aquí .


Puede haber una versión futura de Java (10 o más).

Consulte JEPS 8196004 de enero de 2018: ( "JEP" es el "Programa de mejora de JDK" )

Borrador JEP: Literales de cadenas sin procesar

Agregue un nuevo tipo de literal, un literal de cadena sin formato, al lenguaje de programación Java.
Al igual que el literal de cadena tradicional, un literal de cadena sin formato produce una cadena, pero no interpreta los escapes de cadena y puede abarcar varias líneas de código fuente .

Entonces en lugar de:

Runtime.getRuntime().exec("\"C:\\Program Files\\foo\" bar");
String html = "<html>\n"
              "    <body>\n" +
              "         <p>Hello World.</p>\n" +
              "    </body>\n" +
              "</html>\n";
System.out.println("this".matches("\\w\\w\\w\\w"));

Podrías escribir:

Runtime.getRuntime().exec(`"C:\Program Files\foo" bar"`);
    
String html = `<html>
                   <body>
                       <p>Hello World.</p>
                   </body>
               </html>
              `;

System.out.println("this".matches(`\w\w\w\w`));

¡Ordenado!

Pero sigue siendo solo un borrador : deberá publicarse, enviarse, ser candidato y financiarse antes de completarse y convertirse en el próximo JDK.

VonC
fuente
5

Respuesta simple: No.

Para cadenas más largas que deben escaparse, generalmente las leo de algún recurso externo.

Chris Lercher
fuente
4

también puede usar StringEscapeUtils de apache commons

ACTUALIZACIÓN : Si alguien está interesado en algunos ejemplos, aquí hay un enlace útil: https://dzone.com/articles/commons-lang-3-improved-and-powerful-StringEscapeUtils

Doua Beri
fuente
2
¿Podría agregar un ejemplo posiblemente basado en la pregunta que ilustra cómo solucionar este problema?
Bengt
3
Se considera subóptimo hacer referencia solo a otro recurso que pueda responder la pregunta. Considere resumir la página vinculada con un ejemplo que coincida con la pregunta.
Bengt
Eché un vistazo y no creo que ninguno de los dos realmente responda a la pregunta. Las entradas a los métodos estáticos son Strings, por lo que no hay forma de tener un valor bien formateado en su código. Es de suponer que podrías usar estos métodos para leer de un archivo a un archivo String, pero no creo que esa sea la pregunta aquí.
Tom Harrison
La clase vinculada (org.apache.commons.lang3.StringEscapeUtils) ha sido obsoleta y reemplazada por org.apache.commons.text.StringEscapeUtils
jcarter
-4

Lo siguiente parece funcionar para mí:

String x = "Some Text" + '"' + "More Text" + '"' + "Even More Text";

Creo que debido a que char es el tipo de variable primitiva para String, Strings y chars se pueden combinar (al menos el compilador de eclipse no parece quejarse).

Persona anónima
fuente
1
Creo que porque char es el tipo de variable primitiva para String <- Su suposición es incorrecta. De hecho, también funcionará con un tipo diferente, como un int, así: String x = "Algún texto" + 33 + "Más texto";
Najeeb
-6

Si desea escapar 'o "en su cadena, puede usar el siguiente código:

String text = ...

text = text.replaceAll("('|\")", "\\\\$1");
SreejithVS
fuente
La pregunta se hacía sobre cadenas literales en el código fuente. Perdón intente de nuevo.
michaelb958 - GoFundMonica