J'essaie de créer une application qui correspond à un modèle de message avec un message qu'un utilisateur tente d'envoyer. J'utilise Java regex pour faire correspondre le message. Le modèle / message peut contenir des caractères spéciaux.
Comment obtenir la liste complète des caractères spéciaux qui doivent être échappés pour que mon expression régulière fonctionne et corresponde dans le maximum de cas possibles?
Existe-t-il une solution universelle pour échapper tous les caractères spéciaux dans Java regex?
\Q
et\E
] est considéré comme échappé" - sauf les autres\Q
et\E
les (qui peuvent potentiellement se produire dans le regex original). Il vaut donc mieux utiliserPattern.quote
comme suggéré ici et ne pas réinventer la roue.\.[]{}()<>*+-=!?^$|
]
et}
) ne doivent être échappés qu'après ouverture du même type de support.[]
crochets, certains caractères (comme+
et-
) fonctionnent parfois sans échappement.la source
-
intérieur[]
peut ne pas toujours fonctionner car il est utilisé pour définir des plages. Il est plus sûr d'y échapper. Par exemple, les motifs[-]
et[-)]
correspondent à la chaîne-
mais pas avec[(-)]
.-=!
n'ont pas nécessairement besoin d'être échappés, cela dépend du contexte. Par exemple, comme une seule lettre, ils fonctionnent comme une expression régulière constante.Pour échapper, vous pouvez simplement utiliser ceci à partir de Java 1.5 :
Vous correspondrez exactement au mot
$test
la source
Selon la page de documentation des littéraux de chaîne / métacaractères , ils sont:
<([{\^-=$!|]})?*+.>
De plus, ce serait cool d'avoir cette liste référencée quelque part dans le code, mais je ne sais pas où cela pourrait être ...
la source
String escaped = tnk.replaceAll("[\\<\\(\\[\\{\\\\\\^\\-\\=\\$\\!\\|\\]\\}\\)\\?\\*\\+\\.\\>]", "\\\\$0");
s.replaceAll("[\\W]", "\\\\$0")
où\W
désigne des caractères non mot.En combinant ce que tout le monde a dit, je propose ce qui suit, de garder la liste des caractères spéciaux à RegExp clairement listés dans leur propre chaîne, et d'éviter d'avoir à essayer d'analyser visuellement des milliers de "\\". Cela semble fonctionner assez bien pour moi:
la source
Sur la suggestion de @ Sorin concernant les documents Java Pattern, il semble que les caractères à échapper soient au moins:
la source
String escaped = regexString.replaceAll("([\\\\\\.\\[\\{\\(\\*\\+\\?\\^\\$\\|])", "\\\\$1");
)
doit également être échappé, et selon que vous êtes à l'intérieur ou à l'extérieur d'une classe de caractères, il peut y avoir plus de caractères à échapper, auquel casPattern.quote
fait un assez bon travail pour échapper une chaîne à utiliser à la fois à l'intérieur et à l'extérieur de la classe de caractères.Le
Pattern.quote(String s)
genre de fait ce que vous voulez. Cependant il laisse un peu à désirer; il n'échappe pas réellement les caractères individuels, il enveloppe simplement la chaîne avec\Q...\E
.Il n'y a pas de méthode qui fait exactement ce que vous recherchez, mais la bonne nouvelle est qu'il est en fait assez simple d'échapper à tous les caractères spéciaux d'une expression régulière Java:
Pourquoi ça marche? Eh bien, la documentation pour
Pattern
dit spécifiquement qu'il est permis d'échapper aux caractères non alphabétiques qui ne doivent pas nécessairement être échappés:Par exemple,
;
n'est pas un caractère spécial dans une expression régulière. Cependant, si vous y échappez,Pattern
sera toujours interprété\;
comme;
. Voici quelques exemples supplémentaires:>
devient\>
ce qui équivaut à>
[
devient\[
qui est la forme échappée de[
8
est toujours8
.\)
devient\\\)
qui est les formes échappées\
et(
concaténées.Remarque: La clé est la définition de «non alphabétique», qui dans la documentation signifie en réalité des caractères «non- mots », ou des caractères en dehors du jeu de caractères
[a-zA-Z_0-9]
.la source
de l'autre côté de la pièce, vous devez utiliser l'expression régulière "non-char" qui ressemble à ceci si les caractères spéciaux = allChars - nombre - ABC - espace dans le contexte de votre application.
la source
bien que la réponse soit pour Java, mais le code peut être facilement adapté à partir de cette extension de chaîne Kotlin que j'ai créée (adaptée de ce @brcolow fourni):
impressions
\(\.\*\)
vérifiez-le en action ici https://pl.kotl.in/h-3mXZkNE
la source
En supposant que vous avez et que vous faites confiance (pour faire autorité) la liste des caractères d'échappement que Java regex utilise (ce serait bien si ces caractères étaient exposés dans un membre de la classe Pattern), vous pouvez utiliser la méthode suivante pour échapper le caractère si cela est effectivement nécessaire:
la source