Estou tentando criar um aplicativo que corresponda a um modelo de mensagem com uma mensagem que um usuário está tentando enviar. Estou usando Java regex para corresponder à mensagem. O modelo / mensagem pode conter caracteres especiais.
Como obteria a lista completa de caracteres especiais que precisam ser escapados para que minha regex funcione e corresponda no máximo de casos possíveis?
Existe uma solução universal para escapar de todos os caracteres especiais no Java regex?
\Q
e\E
] é considerado como escapado" - exceto outros\Q
'se\E
' (que podem ocorrer potencialmente dentro do regex original). Então, é melhor usarPattern.quote
como sugerido aqui e não reinventar a roda.\.[]{}()<>*+-=!?^$|
]
e}
) só precisam ser escapados após a abertura do mesmo tipo de colchete.[]
colchetes, alguns caracteres (como+
e-
) às vezes funcionam sem escape.fonte
-
em[]
pode funcionar, pois é usado para definir intervalos. É mais seguro escapar disso. Por exemplo, os padrões[-]
e[-)]
correspondem à string,-
mas não com[(-)]
.-=!
não precisa necessariamente de escape, depende do contexto. Por exemplo, como uma única letra, eles funcionam como um regex constante.Para escapar, você pode apenas usar isso do Java 1.5 :
Você vai corresponder exatamente à palavra
$test
fonte
De acordo com a página de documentação de Literais de String / Metacaracteres , eles são:
<([{\^-=$!|]})?*+.>
Também seria legal ter essa lista referenciada em algum lugar no código, mas não sei onde isso poderia estar ...
fonte
String escaped = tnk.replaceAll("[\\<\\(\\[\\{\\\\\\^\\-\\=\\$\\!\\|\\]\\}\\)\\?\\*\\+\\.\\>]", "\\\\$0");
s.replaceAll("[\\W]", "\\\\$0")
onde\W
designa caracteres não-word.Combinando o que todos disseram, proponho o seguinte, para manter a lista de caracteres especiais para RegExp claramente listados em sua própria String e para evitar ter que tentar analisar visualmente milhares de "\\" 's. Isso parece funcionar muito bem para mim:
fonte
Na sugestão de @Sorin dos documentos do Java Pattern, parece que os caracteres para escapar são pelo menos:
fonte
String escaped = regexString.replaceAll("([\\\\\\.\\[\\{\\(\\*\\+\\?\\^\\$\\|])", "\\\\$1");
)
também deve ser escapado, e dependendo se você está dentro ou fora de uma classe de caractere, pode haver mais caracteres para escapar, caso em quePattern.quote
faz um bom trabalho em escapar uma string para uso dentro e fora da classe de caractere.O
Pattern.quote(String s)
tipo de faz o que você quer. No entanto, deixa um pouco a desejar; na verdade não escapa os caracteres individuais, apenas envolve a string com\Q...\E
.Não existe um método que faça exatamente o que você está procurando, mas a boa notícia é que é bastante simples escapar de todos os caracteres especiais em uma expressão regular Java:
Por que isso funciona? Bem, a documentação para
Pattern
diz especificamente que é permitido escapar caracteres não alfabéticos que não necessariamente precisam ser escapados:Por exemplo,
;
não é um caractere especial em uma expressão regular. No entanto, se você escapar,Pattern
ainda interpretará\;
como;
. Aqui estão mais alguns exemplos:>
torna-se o\>
que é equivalente a>
[
torna-se o\[
que é a forma escapada de[
8
está parado8
.\)
torna-se\\\)
qual é as formas escapadas\
e(
concatenadas.Observação: a chave é a definição de "não alfabético", que na documentação realmente significa caracteres "não palavra " ou caracteres fora do conjunto de caracteres
[a-zA-Z_0-9]
.fonte
do outro lado da moeda, você deve usar regex "não-char" que se pareça com este se caracteres especiais = allChars - número - ABC - espaço no contexto do seu aplicativo.
fonte
embora a resposta seja para Java, mas o código pode ser facilmente adaptado a partir desta extensão Kotlin String que criei (adaptado daquele @brcolow fornecido):
estampas
\(\.\*\)
verifique-o em ação aqui https://pl.kotl.in/h-3mXZkNE
fonte
Supondo que você tenha e confie (para ser autoritário) a lista de caracteres de escape que a regex Java usa (seria bom se esses caracteres fossem expostos em algum membro da classe Pattern), você pode usar o seguinte método para escapar o caractere se for realmente necessário:
fonte