In Java, c'è un modo per scrivere una stringa letterale senza dover sfuggire alle virgolette?


111

Supponiamo che tu abbia una stringa letterale con molte virgolette al suo interno. Potresti sfuggire a tutti, ma è un dolore e difficile da leggere.

In alcune lingue, puoi semplicemente farlo:

foo = '"Hello, World"';

In Java, tuttavia, ''è usato per chars, quindi non puoi usarlo per Strings in questo modo. Alcuni linguaggi hanno una sintassi per aggirare questo problema. Ad esempio, in Python, puoi fare questo:

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

Java ha qualcosa di simile?



Questa risposta mostra come incollare stringhe con escape su più righe in Eclispe.
Jeff Axelrod

2
Aggiornamento 2018: potrebbero essere in arrivo stringhe letterali non elaborate per Java. Vedi la mia risposta di seguito
VonC

importare Jackson ObjectMapper quindi System.out.println(mapperObj.writeValueAsString(mapperObj.readValue(str, Object.class)));
Kervvv

aggiornamento Q4 2018: la stringa letterale grezza non è ancora arrivata. Vedi la mia risposta aggiornata .
VonC

Risposte:


74

La risposta è no e la prova risiede nella specifica del linguaggio Java :

  StringLiteral:
   "StringCharacters"

  StringCharacters:
   StringCharacter
   | StringCharacters StringCharacter

  StringCharacter:
   InputCharacter but not " or \
   | EscapeSequence

Come puoi vedere, un StringLiteralpuò essere semplicemente vincolato da "e non può contenere caratteri speciali senza escape ..

Una nota a margine: puoi incorporare Groovy all'interno del tuo progetto, questo estenderà la sintassi di Java permettendoti di usare '''multi line string ''', ' "string with single quotes" 'e anche "string with ${variable}".


141

No, e sono sempre stato infastidito dalla mancanza di diverse sintassi letterali stringa in Java.

Ecco un trucco che ho usato di tanto in tanto:

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

Principalmente faccio qualcosa del genere solo per un campo statico. Poiché è statico, il codice di sostituzione della stringa viene chiamato una volta, al momento dell'inizializzazione della classe. Quindi la penalizzazione delle prestazioni di runtime è praticamente inesistente e rende il codice notevolmente più leggibile.


non avresti bisogno di utilizzare replaceAll?
Landon Kuhn

10
@ landon9720 No, .replace sostituisce tutte le occorrenze di una sequenza di caratteri / caratteri con un'altra sequenza di caratteri / caratteri. .replaceAll utilizza regex.
abelito

Per curiosità sai se il compilatore java semplificherebbe questo durante la compilazione?
ug_

2
No, non credo che il compilatore lo semplificherebbe. Ma non importa davvero. È una chiamata molto economica e se lo faccio solo per stringhe finali statiche, il costo verrà sostenuto solo una volta, al caricamento della classe. Questo è un prezzo che di solito sono disposto a pagare per un codice dall'aspetto più carino :)
carino

3
Allora che dire di "\" in myString?
Anderson

10

Aggiornamento dicembre 2018 (12 mesi dopo):

I valori letterali delle stringhe grezze (che sono nella lista ambra ) non arriveranno a JDK 12.
Vedi le critiche qui .


Potrebbe esserci in una futura versione di Java (10 o più).

Vedi JEPS 8196004 da gennaio 2018: ( "JEP" è il "JDK Enhancement Program" )

Bozza JEP: Raw String Literals

Aggiungi un nuovo tipo di letterale, una stringa letterale non elaborata, al linguaggio di programmazione Java.
Come la stringa letterale tradizionale, una stringa letterale non elaborata produce una stringa, ma non interpreta gli escape di stringa e può estendersi su più righe di codice sorgente .

Quindi invece di:

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"));

Sarai in grado di digitare:

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`));

! Neat

Ma è ancora solo una bozza : dovrà essere pubblicata, presentata, essere un candidato e finanziato, prima di essere completato e diventare il prossimo JDK.


5

Risposta semplice: no.

Per stringhe più lunghe di cui è necessario eseguire l'escape, di solito le leggo da una risorsa esterna.


4

puoi anche usare StringEscapeUtils da apache commons

AGGIORNAMENTO : Se qualcuno è interessato ad alcuni esempi ecco un link utile: https://dzone.com/articles/commons-lang-3-improved-and-powerful-StringEscapeUtils


2
Potresti aggiungere un esempio possibilmente basato sulla domanda che illustra come farlo per questo problema?
Bengt

3
È considerato non ottimale fare riferimento solo a un'altra risorsa che potrebbe rispondere alla domanda. Considera la possibilità di riassumere la pagina collegata con un esempio corrispondente alla domanda.
Bengt

Ho dato un'occhiata e non credo che nessuno dei due risponda davvero alla domanda. Gli input per i metodi statici sono Strings, quindi non c'è modo di avere un valore ben formattato nel codice. Presumibilmente potresti usare questi metodi per leggere da un file in un String, ma non credo che questa sia la domanda qui.
Tom Harrison

La classe collegata (org.apache.commons.lang3.StringEscapeUtils) è stata deprecata e sostituita con org.apache.commons.text.StringEscapeUtils
jcarter

-4

Quanto segue sembra funzionare per me:

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

Penso che poiché char è il tipo di variabile primitiva per String, stringhe e chars possono essere combinati (almeno il compilatore eclipse non sembra lamentarsi).


1
Penso che perché char è il tipo di variabile primitiva per String <- La tua ipotesi non è corretta. Del resto, funzionerà anche con un tipo diverso, come un int, in questo modo: String x = "Some text" + 33 + "More text";
Najeeb

-6

Se vuoi fare l'escape 'o "nella tua stringa, puoi usare il seguente codice:

String text = ...

text = text.replaceAll("('|\")", "\\\\$1");

La domanda è stata posta sulle stringhe letterali nel codice sorgente. Mi dispiace riprova.
michaelb958 - GoFundMonica
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.