Jak uciec% w String.Format?


445

Przechowuję zapytanie SQL w moim pliku strings.xml i chcę użyć go String.Formatdo zbudowania ostatniego ciągu w kodzie. W SELECToświadczeniu używa się czegoś podobnego:

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

Aby sformatować, zamieniam „coś” na% 1 $ s, aby stało się:

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

Unikam pojedynczych cudzysłowów odwrotnym ukośnikiem. Nie jestem jednak w stanie uciec od znaku%.

Jak mogę dołączyć podobną instrukcję do mojego pliku strings.xml?


Nie zapomnij odpowiednio uciec z% s.
Seva Alekseyev


Będą wstrzykiwać do własnej bazy danych, bez względu na to;)
Matthew

7
Cóż, nawet jeśli jest to Twoja własna baza danych, możliwe jest przypadkowe pisanie zapytań, które robią złe rzeczy. Lub po prostu napisz zapytania, które się nie kompilują. Przygotowanie zapytań jest dobrym nawykiem.
Rauni Lillemets

Chociaż jest wolniejszy, niż String.format()możesz rozważyć użycie MessageFormat()zamiast niego.
ccpizza

Odpowiedzi:



14

Aby uzupełnić poprzednie podane rozwiązanie, użyj:

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

1
Spowoduje to zastąpienie%, które są już podwojone. Przeczytaj drugą odpowiedź.
Toilal 27.07.16

1
@Toilal Dlaczego ktokolwiek miałby uciekać przed czymś, co już uciekło? A jeśli by tak zrobił, dlaczego właściwie tego nie zrobić? Może zamierzał mieć dwa znaki%, więc poprawną formą zmiany znaczenia będzie „%%%%”
David Balažic

2

Jest to silniejsze zastępowanie wyrażeń regularnych, które nie zastąpi %%, które są już podwojone w danych wejściowych.

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

-3

Oto opcja, jeśli musisz uciec wielu% w ciągu, a niektóre już uciekły.

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

Aby zdezynfekować wiadomość przed przekazaniem jej do String.format, możesz użyć następujących

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

Działa to z dowolną liczbą znaków formatujących, więc zastąpi%%%, %%% z %%%%, %%%%% z %%%%%% itp.

Pozostawi już wszelkie znaki, które uciekły w spokoju (np. %%, %%%% itp.)


8
„Nie mogę uwierzyć, że nie jest to do tej pory prosty rozwiązany problem” << Odpowiedziałeś 6 lat po przyjęciu prostego rozwiązania.
AjahnCharles
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.