Wie entkomme ich% in String.Format?

445

Ich speichere eine SQL-Abfrage in meiner Datei strings.xml und möchte String.Formatdamit die endgültige Zeichenfolge im Code erstellen. Die SELECTAnweisung verwendet ein "Gefällt mir", etwa so:

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

Um zu formatieren, dass ich 'etwas' durch% 1 $ s ersetze, wird es:

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

Ich entkomme den einfachen Anführungszeichen mit dem Backslash. Ich kann mich jedoch dem% -Zeichen nicht entziehen.

Wie kann ich eine ähnliche Anweisung in meine Datei strings.xml aufnehmen?

Matthew
quelle
Vergiss nicht, den% s richtig zu entkommen.
Seva Alekseyev
Sie würden in ihre eigene Datenbank injizieren, keine Sorge hier;)
Matthew
7
Nun, selbst wenn es sich um Ihre eigene Datenbank handelt, ist es möglich, versehentlich Abfragen zu schreiben, die schlechte Dinge bewirken. Oder schreiben Sie einfach Abfragen, die nicht kompiliert werden. Das Vorbereiten von Abfragen ist eine gute Angewohnheit.
Rauni Lillemets
Obwohl es langsamer ist, als String.format()Sie vielleicht in Betracht ziehen MessageFormat().
ccpizza

Antworten:

925

Um zu entkommen %, müssen Sie es verdoppeln : %%.

limc
quelle
14

Verwenden Sie zur Ergänzung der zuvor angegebenen Lösung:

str = str.replace("%", "%%");
Cavaleiro
quelle
1
Dies ersetzt%, die bereits verdoppelt wurden. Bitte lesen Sie die andere Antwort.
Toilette
1
@Toilal Warum sollte jemand etwas entkommen, das bereits entkommen ist? Und wenn ja, warum nicht? Vielleicht wollte er zwei% -Zeichen haben, also wäre die korrekte Escape-Form '%%%%'
David Balažic
2

Dies ist eine stärkere Regex-Ersetzung, die %% nicht ersetzt, die bereits in der Eingabe verdoppelt wurden.

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

Hier ist eine Option, wenn Sie mehrere% in einer Zeichenfolge maskieren müssen, wobei einige bereits maskiert sind.

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

Um die Nachricht zu bereinigen, bevor sie an String.format übergeben wird, können Sie Folgendes verwenden

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

Dies funktioniert mit einer beliebigen Anzahl von Formatierungszeichen, sodass% durch %%, %%% durch %%%%, %%%%% durch %%%%%% usw. ersetzt wird.

Bereits maskierte Zeichen (z. B. %%, %%%% usw.) bleiben in Ruhe.

Lee Winder
quelle
8
"Ich kann nicht glauben, dass dies bis jetzt kein einfach gelöstes Problem ist" << Sie antworteten 6 Jahre nachdem eine einfache Lösung akzeptiert wurde.
AjahnCharles