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?


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 : %%.


14

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

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

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

-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.


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.