Làm thế nào để thoát% trong String.Format?


445

Tôi đang lưu trữ một truy vấn SQL trong tệp String.xml của mình và tôi muốn sử dụng String.Formatđể xây dựng chuỗi cuối cùng trong mã. Câu SELECTlệnh sử dụng một like, đại loại như thế này:

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

Để định dạng mà tôi thay thế 'một cái gì đó' bằng% 1 $ s để nó trở thành:

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

Tôi thoát khỏi dấu ngoặc đơn với dấu gạch chéo ngược. Tuy nhiên tôi không thể thoát khỏi dấu%.

Làm cách nào tôi có thể bao gồm một câu lệnh like trong tệp String.xml của mình?


Đừng quên thoát% s đúng cách.
Seva Alekseyev


Họ sẽ được đưa vào cơ sở dữ liệu của riêng họ, không cần quan tâm ở đây;)
Matthew

7
Chà, ngay cả khi đó là cơ sở dữ liệu của riêng bạn, có thể vô tình viết các truy vấn làm điều xấu. Hoặc chỉ viết các truy vấn không biên dịch. Chuẩn bị truy vấn là một thói quen tốt để có được vào.
Rauni Lillemets

Mặc dù nó chậm hơn String.format()bạn có thể cân nhắc sử dụng MessageFormat()thay thế.
ccpizza

Câu trả lời:


926

Để thoát ra %, bạn sẽ cần phải nhân đôi nó lên:%% .


14

Để bổ sung cho giải pháp đã nêu trước đó, hãy sử dụng:

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

1
Điều này sẽ thay thế% đã được nhân đôi. Xin vui lòng đọc câu trả lời khác.
Toilal

1
@Toilal Tại sao mọi người sẽ thoát khỏi một cái gì đó đã thoát? Và nếu anh ta sẽ, tại sao không thực sự làm điều đó? Có lẽ anh ta dự định có hai% ký hiệu, vì vậy hình thức thoát chính xác sẽ là '%%%%'
David Balažic

2

Đây là một thay thế regex mạnh hơn sẽ không thay thế %% đã được nhân đôi trong đầu vào.

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

-3

Đây là một tùy chọn nếu bạn cần thoát nhiều% trong một chuỗi với một số đã thoát.

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

Để vệ sinh tin nhắn trước khi gửi nó đến String.format, bạn có thể sử dụng như sau

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

Điều này hoạt động với bất kỳ số lượng ký tự định dạng nào, do đó, nó sẽ thay thế% bằng %%, %%% bằng %%%, %%%%% bằng %%%%%

Nó sẽ để bất kỳ ký tự nào đã thoát một mình (ví dụ: %%, %%%%, v.v.)


8
"Tôi không thể tin rằng bây giờ đây không phải là một vấn đề đơn giản được giải quyết" << Bạn đã trả lời 6 năm sau khi một giải pháp đơn giản được chấp nhận.
AjahnCharles
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.