2011-02-16 19 views
274

Estoy almacenando una consulta SQL en mi archivo strings.xml y deseo usar String.Format para construir la cadena final en el código. La declaración SELECT utiliza una similar, algo como esto:Cómo escapar% en String.Format?

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

Con el fin de formato que sustituyo 'algo' con% 1 $ s por lo que se convierte en:

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

me escape las comillas simples con la barra invertida. Sin embargo, no puedo escapar del signo%.

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

+0

No olvides escaparte el% s correctamente. –

+15

[alerta de inyección SQL] (http://unixwiz.net/techtips/sql-injection.html). [Prepárese] (http://download.oracle.com/javase/tutorial/jdbc/basics/prepared.html). – BalusC

+0

Ellos estarían inyectando en su propia base de datos, no importa aquí;) – Matthew

Respuesta

602

Para escapar %, tendrá que duplicarlo: %%.

+4

¿estoy ciego o falta esta información en el Formatter Javadoc? O.o –

+1

Es difícil de encontrar, pero en mi versión, al menos, lo veo ... _El resultado es un literal '%' ('\ u0025') _ –

10

Para complementar la anterior solución se ha dicho, el uso:

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

Esto reemplazará el% que ya se ha duplicado. Por favor, lea la otra respuesta. – Toilal

1

Ésta es una expresión regular más fuerte que lo sustituya por no reemplazará %% que ya se duplicó en la entrada.

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

No puedo creer que esto no es un problema resuelto sencilla a estas alturas, pero bueno, aquí está mi puñalada en ella

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

Para desinfectar el mensaje antes de pasarla a String.Format , puede utilizar el 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(); 

Tenga en cuenta que esto funciona con cualquier número de caracteres de formato, por lo que va a sustituir% con %%, %%% con %%%%, %%%%% con %% %%%% etc.

Dejará solo los caracteres ya escapados (p. %%, %%%% etc.)