¿Cómo escapar% en String.Format?


445

Estoy almacenando una consulta SQL en mi archivo strings.xml y quiero usar String.Formatpara construir la cadena final en el código. La SELECTdeclaración usa un me gusta, algo como esto:

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

Para formatear eso, reemplazo 'algo' con% 1 $ s para que se convierta en:

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

Me escapo de las comillas simples con la barra diagonal inversa. Sin embargo, no puedo escapar del signo%.

¿Cómo puedo incluir una declaración similar en mi archivo strings.xml?


No olvides escapar del% s correctamente.
Seva Alekseyev


Estarían inyectando en su propia base de datos, sin preocupación aquí;)
Matthew

77
Bueno, incluso si se trata de su propia base de datos, es posible escribir accidentalmente consultas que hacen cosas malas. O simplemente escriba consultas que no se compilan. Preparar consultas es un buen hábito.
Rauni Lillemets

Aunque es más lento de lo String.format()que podrías considerar usar en su MessageFormat()lugar.
ccpizza

Respuestas:


926

Para escapar %, tendrá que doblar hacia arriba: %%.


14

Para complementar la solución establecida anteriormente, use:

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

1
Esto reemplazará el% que ya está duplicado. Por favor lea la otra respuesta.
Toilal

1
@Toilal ¿Por qué alguien escaparía de algo que ya se ha escapado? Y si lo hiciera, ¿por qué no hacerlo? Tal vez tenía la intención de tener dos signos de%, por lo que la forma correcta de escape sería '%%%%'
David Balažic

2

Este es un reemplazo de expresiones regulares más fuerte que no reemplazará %% que ya están duplicados en la entrada.

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

-3

Aquí hay una opción si necesita escapar de varios% 's en una cadena con algunos ya escapados.

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

Para desinfectar el mensaje antes de pasarlo a String.format, puede usar lo siguiente

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

Esto funciona con cualquier número de caracteres de formato, por lo que reemplazará% con %%, %%% con %%%%, %%%%% con %%%%%% etc.

Dejará solos los caracteres ya escapados (por ejemplo, %%, %%%% etc.)


8
"No puedo creer que este no sea un problema simple resuelto por ahora" << Respondiste 6 años después de que se aceptara una solución simple.
AjahnCharles
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.