Bagaimana cara menghindari% di String.Format?


445

Saya menyimpan query SQL dalam file strings.xml saya dan saya ingin menggunakan String.Formatuntuk membangun string terakhir dalam kode. The SELECTpernyataan menggunakan seperti, sesuatu seperti ini:

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

Untuk memformat yang saya ganti 'sesuatu' dengan% 1 $ s sehingga menjadi:

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

Saya lolos dari tanda kutip tunggal dengan garis miring terbalik. Namun saya tidak dapat lepas dari tanda%.

Bagaimana saya bisa memasukkan pernyataan suka dalam file strings.xml saya?


Jangan lupa untuk keluar dari% s dengan benar.
Seva Alekseyev


Mereka akan menyuntikkan ke dalam database mereka sendiri, tidak ada masalah di sini;)
Matius

7
Yah, bahkan jika itu adalah database Anda sendiri, adalah mungkin untuk secara tidak sengaja menulis pertanyaan yang melakukan hal-hal buruk. Atau cukup tulis pertanyaan yang tidak dikompilasi. Mempersiapkan pertanyaan adalah kebiasaan yang baik untuk dilakukan.
Rauni Lillemets

Meskipun lebih lambat dari String.format()yang mungkin Anda pertimbangkan untuk menggunakannya MessageFormat().
ccpizza

Jawaban:


926

Untuk melarikan diri %, Anda akan perlu dua itu: %%.


14

Untuk melengkapi solusi yang dinyatakan sebelumnya, gunakan:

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

1
Ini akan menggantikan% yang sudah dua kali lipat. Silakan baca jawaban lainnya.
Toilal

1
@Toalal Mengapa ada orang yang lolos dari sesuatu yang sudah lolos? Dan jika dia mau, mengapa tidak benar-benar melakukannya? Mungkin dia bermaksud memiliki dua tanda%, jadi bentuk yang benar yang lolos adalah '%%%%'
David Balažic

2

Ini adalah pengganti regex yang lebih kuat yang tidak akan menggantikan %% yang sudah dua kali lipat dalam input.

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

-3

Berikut adalah opsi jika Anda perlu melarikan diri beberapa% dalam sebuah string dengan beberapa sudah lolos.

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

Untuk membersihkan pesan sebelum meneruskannya ke String.format, Anda dapat menggunakan yang berikut ini

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

Ini berfungsi dengan sejumlah karakter pemformatan, sehingga akan menggantikan% dengan %%, %%% dengan %%%%, %%%%% dengan %%%%%%, dll.

Ini akan membiarkan karakter yang sudah lolos saja (mis. %%, %%%%, dll.)


8
"Aku tidak percaya bahwa ini bukan masalah yang mudah diselesaikan sekarang" << Anda menjawab 6 tahun setelah solusi sederhana diterima.
AjahnCharles
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.