referencia Cada SQL dice que puedo encontrar el comodín "cualquier carácter individual" es el guión bajo (_
), no es el signo de interrogación (?
). Eso simplifica un poco las cosas, ya que el guión bajo no es un metacaracter regex. Sin embargo, todavía no puede usar Pattern.quote()
por el motivo dado por mmyers. Aquí tengo otro método para escapar de las expresiones regulares cuando me gustaría editarlas después. Con eso fuera del camino, el método like()
vuelve bastante simple:
public static boolean like(final String str, final String expr)
{
String regex = quotemeta(expr);
regex = regex.replace("_", ".").replace("%", ".*?");
Pattern p = Pattern.compile(regex,
Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
return p.matcher(str).matches();
}
public static String quotemeta(String s)
{
if (s == null)
{
throw new IllegalArgumentException("String cannot be null");
}
int len = s.length();
if (len == 0)
{
return "";
}
StringBuilder sb = new StringBuilder(len * 2);
for (int i = 0; i < len; i++)
{
char c = s.charAt(i);
if ("[](){}.*+?$^|#\\".indexOf(c) != -1)
{
sb.append("\\");
}
sb.append(c);
}
return sb.toString();
}
Si realmente desea utilizar ?
por el comodín, lo mejor sería eliminar de la lista de metacaracteres en el método quotemeta()
. Reemplazar su forma de escape - replace("\\?", ".")
- no sería seguro porque podría haber barras invertidas en la expresión original.
Y eso nos lleva a los problemas reales: la mayoría de sabores de SQL parecen apoyar las clases de personajes en las formas [a-z]
y [^j-m]
o [!j-m]
, y todos ellos proporcionan una manera de escapar caracteres comodín. Este último generalmente se realiza mediante una palabra clave ESCAPE
, que le permite definir un carácter de escape diferente cada vez. Como se puede imaginar, esto complica bastante las cosas. La conversión a una expresión regular probablemente sea todavía la mejor opción, pero el análisis de la expresión original será mucho más difícil; de hecho, lo primero que tendría que hacer es formalizar la sintaxis de las expresiones similares a LIKE
.
sí, gracias! Pero en caso de que la palabra no sea tan simple como "% dig%" y la cadena necesita algo de escpeo? ¿Hay algo que ya exista? Qué pasa con la '?' ? – Chris
Edité mi respuesta para el operador del signo de interrogación. Aunque estoy un poco confundido por el resto de tu comentario. ¿Estás diciendo que la cadena viene hacia ti en sintaxis SQL y quieres evaluarla tal como está? Si ese es el caso, creo que deberá reemplazar manualmente la sintaxis sql. – Bob
¿Qué sucede si la cadena que se utiliza como patrón de búsqueda contiene caracteres de agrupación como '(' o ')' también para escapar? ¿Cómo pueden escapar otros personajes? – Chris