Estoy intentando crear una aplicación que coincida con una plantilla de mensaje con un mensaje que un usuario está intentando enviar. Estoy usando Java regex para hacer coincidir el mensaje. La plantilla / mensaje puede contener caracteres especiales.
¿Cómo obtendría la lista completa de caracteres especiales que deben escaparse para que mi expresión regular funcione y coincida en el máximo de casos posibles?
¿Existe una solución universal para escapar de todos los caracteres especiales en Java regex?
\Q
y\E
] se considera escapado" , excepto los de otros\Q
y\E
(que potencialmente pueden ocurrir dentro de la expresión regular original). Por lo tanto, es mejor usarloPattern.quote
como se sugiere aquí y no reinventar la rueda.\.[]{}()<>*+-=!?^$|
]
y}
) después de abrir el mismo tipo de soporte.[]
paréntesis, algunos caracteres (como+
y-
) a veces funcionan sin escape.fuente
-
interior sin escape[]
no siempre funcione, ya que se utiliza para definir rangos. Es más seguro escapar de él. Por ejemplo, los patrones[-]
y[-)]
coinciden con la cadena-
pero no con[(-)]
.-=!
no necesariamente es necesario escapar, depende del contexto. Por ejemplo, como una sola letra, funcionan como una expresión regular constante.Para escapar, puede usar esto de Java 1.5 :
Coincidirás exactamente con la palabra
$test
fuente
De acuerdo con la página de documentación de String Literals / Metacharacters , son:
<([{\^-=$!|]})?*+.>
También sería genial tener esa lista referenciada en algún lugar del código, pero no sé dónde podría estar ...
fuente
String escaped = tnk.replaceAll("[\\<\\(\\[\\{\\\\\\^\\-\\=\\$\\!\\|\\]\\}\\)\\?\\*\\+\\.\\>]", "\\\\$0");
s.replaceAll("[\\W]", "\\\\$0")
donde\W
designa caracteres que no son palabras.Combinando lo que todos dijeron, propongo lo siguiente, para mantener la lista de caracteres especiales para RegExp claramente enumerados en su propia Cadena, y para evitar tener que intentar analizar visualmente miles de "\\". Esto parece funcionar bastante bien para mí:
fuente
En la sugerencia de @ Sorin de los documentos de Java Pattern, parece que los caracteres para escapar son al menos:
fuente
String escaped = regexString.replaceAll("([\\\\\\.\\[\\{\\(\\*\\+\\?\\^\\$\\|])", "\\\\$1");
)
también tiene que ser escapado, y dependiendo de si estás dentro o fuera de una clase de personaje, puede haber más personajes para escapar, en cuyo casoPattern.quote
hace un buen trabajo al escapar de una cadena para usar tanto dentro como fuera de la clase de personaje.El
Pattern.quote(String s)
tipo de hace lo que quieres. Sin embargo, deja un poco que desear; en realidad no se escapa de los caracteres individuales, solo envuelve la cadena con\Q...\E
.No existe un método que haga exactamente lo que está buscando, pero la buena noticia es que en realidad es bastante simple escapar de todos los caracteres especiales en una expresión regular de Java:
¿Por qué funciona esto? Bueno, la documentación para
Pattern
específicamente dice que está permitido escapar de los caracteres no alfabéticos que no necesariamente tienen que escaparse:Por ejemplo,
;
no es un carácter especial en una expresión regular. Sin embargo, si lo escapas,Pattern
aún se interpretará\;
como;
. Aqui hay algunos ejemplos mas:>
se convierte en lo\>
que es equivalente a>
[
se convierte en\[
cuál es la forma escapada de[
8
está quieto8
.\)
se convierte en lo\\\)
que son las formas escapadas\
y(
concatenadas.Nota: La clave es la definición de "no alfabético", que en la documentación realmente significa caracteres "que no son palabras " o caracteres fuera del conjunto de caracteres
[a-zA-Z_0-9]
.fuente
En el otro lado de la moneda, debe usar expresiones regulares "sin caracteres" que se vean así si los caracteres especiales = allChars - número - ABC - espacio en el contexto de su aplicación.
fuente
aunque la respuesta es para Java, pero el código se puede adaptar fácilmente de esta extensión de Kotlin String que se me ocurrió (adaptado de la que @brcolow proporcionó):
huellas dactilares
\(\.\*\)
compruébalo en acción aquí https://pl.kotl.in/h-3mXZkNE
fuente
Suponiendo que tiene y confía (para ser autorizado) la lista de caracteres de escape que usa Java regex (sería bueno si estos caracteres estuvieran expuestos en algún miembro de la clase Pattern), puede usar el siguiente método para escapar del carácter si es realmente necesario:
fuente