Come sfuggire a% in String.Format?


446

Sto memorizzando una query SQL nel mio file strings.xml e desidero utilizzarlo String.Formatper creare la stringa finale nel codice. La SELECTdichiarazione usa un like, qualcosa del genere:

SELECT Field1, Field2 FROM mytable WHERE Field1 LIKE '%something%'

Per formattare che sostituisco "qualcosa" con% 1 $ s in modo che diventi:

SELECT Field1, Field2 FROM mytable WHERE Field1 LIKE \'%%1$s%\'

Sfuggo alle virgolette singole con la barra rovesciata. Tuttavia, non riesco a sfuggire al segno%.

Come posso includere un'istruzione like nel mio file strings.xml?


Non dimenticare di sfuggire correttamente a% s.
Seva Alekseyev,


Avrebbero iniettato nel proprio database, nessuna preoccupazione qui;)
Matteo

7
Bene, anche se è il tuo database, è possibile scrivere accidentalmente query che fanno cose cattive. O semplicemente scrivere query che non vengono compilate. Preparare le domande è una buona abitudine.
Rauni Lillemets,

Anche se è più lento di quanto String.format()potresti considerare di utilizzare MessageFormat()invece.
ccpizza,

Risposte:


928

Per sfuggire %, è necessario raddoppiare in su: %%.


14

Per integrare la precedente soluzione dichiarata, utilizzare:

str = str.replace("%", "%%");

1
Questo sostituirà% che sono già raddoppiate. Si prega di leggere l'altra risposta.
Toilal,

1
@Toilal Perché qualcuno dovrebbe sfuggire a qualcosa che è già sfuggito? E se lo facesse, perché non farlo davvero? Forse intendeva avere due segni%, quindi la forma di escape corretta sarebbe '%%%%'
David Balažic,

2

Questa è una sostituzione regex più forte che non sostituirà %% che sono già raddoppiati nell'input.

str = str.replaceAll("(?:[^%]|\\A)%(?:[^%]|\\z)", "%%");

-3

Ecco un'opzione se devi scappare più% in una stringa con alcuni già scappati.

(?:[^%]|^)(?:(%%)+|)(%)(?:[^%])

Per disinfettare il messaggio prima di passarlo a String.format, è possibile utilizzare quanto segue

Pattern p = Pattern.compile("(?:[^%]|^)(?:(%%)+|)(%)(?:[^%])");
Matcher m1 = p.matcher(log);

StringBuffer buf = new StringBuffer();
while (m1.find())
    m1.appendReplacement(buf, log.substring(m1.start(), m1.start(2)) + "%%" + log.substring(m1.end(2), m1.end()));

// Return the sanitised message
String escapedString = m1.appendTail(buf).toString();

Funziona con qualsiasi numero di caratteri di formattazione, quindi sostituirà% con %%, %%% con %%%%, %%%%% con %%%%%%% ecc.

Lascerà da solo i caratteri già sfuggiti (ad esempio %%, %%%% ecc.)


8
"Ormai non riesco a credere che questo non sia un semplice problema risolto" << Hai risposto 6 anni dopo l'accettazione di una soluzione semplice.
AjahnCharles,
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.