Je suis fatigué de toujours essayer de deviner, si je dois échapper des caractères spéciaux comme ' ()[]{}|
' etc. lors de l'utilisation de nombreuses implémentations de regexps.
C'est différent avec, par exemple, Python, sed, grep, awk, Perl, rename, Apache, find et ainsi de suite. Y a-t-il un ensemble de règles qui indique quand je devrais et quand je ne devrais pas, échapper des caractères spéciaux? Cela dépend-il du type d'expression régulière, comme PCRE, POSIX ou expressions régulières étendues?
escape()
" pour permettre d'utiliser des chaînes arbitraires comme parties d'expressions régulières.Réponses:
Les personnages que vous devez et ceux que vous ne devez pas échapper dépendent en effet de la saveur regex avec laquelle vous travaillez.
Pour PCRE, et la plupart des autres versions dites compatibles avec Perl, échappez à ces classes de caractères externes:
et ces classes de caractères internes:
Pour les expressions rationnelles étendues POSIX (ERE), échappez à ces classes de caractères externes (identiques à PCRE):
L'échappement de tout autre caractère est une erreur avec POSIX ERE.
Dans les classes de caractères, la barre oblique inverse est un caractère littéral dans les expressions régulières POSIX. Vous ne pouvez pas l'utiliser pour échapper à quoi que ce soit. Vous devez utiliser le "placement intelligent" si vous souhaitez inclure des métacaractères de classe de caractères en tant que littéraux. Mettez le ^ n'importe où sauf au début, le] au début et le - au début ou à la fin de la classe de caractères pour les faire correspondre littéralement, par exemple:
Dans les expressions régulières de base POSIX (BRE), ce sont des métacaractères que vous devez échapper pour supprimer leur signification:
Les parenthèses et les accolades qui s'échappent dans les BRE leur donnent la signification particulière que leurs versions non échappées ont dans les ERE. Certaines implémentations (par exemple GNU) donnent également une signification spéciale à d'autres caractères lorsqu'elles sont échappées, comme \? et +. L'échappement d'un caractère autre que. ^ $ * () {} Est normalement une erreur avec les BRE.
À l'intérieur des classes de personnages, les BRE suivent la même règle que les ERE.
Si tout cela vous fait tourner la tête, prenez une copie de RegexBuddy . Sous l'onglet Créer, cliquez sur Insérer un jeton, puis sur Littéral. RegexBuddy ajoutera des échappements au besoin.
la source
/
n'est pas un métacaractère dans aucune des saveurs d'expression régulière que j'ai mentionnées, donc la syntaxe d'expression régulière ne nécessite pas de s'échapper. Lorsqu'une expression régulière est citée en tant que littéral dans un langage de programmation, les règles de formatage de chaîne ou d'expression régulière de ce langage peuvent nécessiter/
ou"
ou'
être échappées, et peuvent même exiger que `\` soit doublement échappé.Saveurs RegEx modernes (PCRE)
Comprend C, C ++, Delphi, EditPad, Java, JavaScript, Perl, PHP (preg), PostgreSQL, PowerGREP, PowerShell, Python, REALbasic, Real Studio, Ruby, TCL, VB.Net, VBScript, wxWidgets, XML Schema, Xojo, XRegExp.
La compatibilité PCRE peut varier
Nulle part:
. ^ $ * + - ? ( ) [ ] { } \ |
Saveurs RegEx héritées (BRE / ERE)
Inclut awk, ed, egrep, emacs, GNUlib, grep, PHP (ereg), MySQL, Oracle, R, sed.
La prise en charge de PCRE peut être activée dans les versions ultérieures ou à l'aide d'extensions
ERE / awk / egrep / emacs
En dehors d'une classe de personnages:
. ^ $ * + ? ( ) [ { } \ |
Dans une classe de personnages:
^ - [ ]
BRE / ed / grep / sed
À l'extérieur d'une classe de caractères:
. ^ $ * [ \
À l'intérieur d'une classe de caractères:
^ - [ ]
Pour les littéraux, n'échappez pas:
+ ? ( ) { } |
Pour un comportement d'expression régulière standard, échappez:
\+ \? \( \) \{ \} \|
Remarques
\xFF
] -
il suffit de s'échapper dans une classe de caractères, mais je les ai conservés dans une seule liste pour plus de simplicité"(\")(/)(\\.)"
par rapport/(")(\/)(\.)/
à JavaScript)la source
-
ou ne]
doit être échappée en dehors des classes de caractères. POSIX (BRE / ERE) n'a pas de caractère d'échappement dans les classes de caractères. La saveur regex dans le RTL de Delphi est en fait basée sur PCRE. Python, Ruby et XML ont leurs propres versions qui sont plus proches de PCRE que des versions POSIX.Malheureusement, il n'y a vraiment pas de jeu de codes d'échappement car il varie en fonction de la langue que vous utilisez.
Cependant, conserver une page comme la page des outils d'expression régulière ou cette feuille de triche d'expression régulière peut vous aider à filtrer rapidement les choses.
la source
\<
et\>
sont des limites de mots, ce qui est vrai uniquement (AFAIK) dans la bibliothèque d'expressions régulières Boost. Mais ailleurs, il dit<
et>
sont des métacaractères et doivent être échappés (vers\<
et\>
) pour les faire correspondre littéralement, ce qui n'est vrai dans aucune saveurMalheureusement, le sens de choses comme (et \ (sont échangés entre les expressions régulières de style Emacs et la plupart des autres styles. Donc, si vous essayez de les échapper, vous faites peut-être le contraire de ce que vous voulez.
Il faut donc vraiment savoir quel style vous essayez de citer.
la source
POSIX reconnaît plusieurs variantes des expressions régulières - les expressions régulières de base (BRE) et les expressions régulières étendues (ERE). Et même alors, il y a des bizarreries en raison des implémentations historiques des utilitaires standardisés par POSIX.
Il n'y a pas de règle simple pour savoir quand utiliser quelle notation, ou même quelle notation utilise une commande donnée.
Consultez le livre Mastering Regular Expressions de Jeff Friedl .
la source
Vraiment, il n'y en a pas. il existe environ un demi-zillion de syntaxes d'expression régulière différentes; ils semblent se résumer à Perl, EMACS / GNU et AT&T en général, mais je suis toujours aussi surpris.
la source
Parfois, un simple échappement n'est pas possible avec les personnages que vous avez répertoriés. Par exemple, l'utilisation d'une barre oblique inverse pour échapper à un crochet ne fonctionnera pas dans le côté gauche d'une chaîne de substitution dans sed, à savoir
J'ai tendance à utiliser une simple définition de classe de caractères à la place, donc l'expression ci-dessus devient
que je trouve fonctionne pour la plupart des implémentations regexp.
Les classes de caractères BTW sont des composants regexp assez vanille, ils ont donc tendance à fonctionner dans la plupart des situations où vous avez besoin de caractères échappés dans les regexps.
Edit: Après le commentaire ci-dessous, je pensais simplement mentionner le fait que vous devez également prendre en compte la différence entre les automates à états finis et les automates à états non finis lorsque vous examinez le comportement de l'évaluation des expressions rationnelles.
Vous voudrez peut-être regarder "le livre de la balle brillante" aka Effective Perl ( lien Amazon purifié ), en particulier le chapitre sur les expressions régulières, pour avoir une idée de la différence dans les types d'évaluation du moteur d'expression rationnelle.
Tout le monde n'est pas un PCRE!
Quoi qu'il en soit, les expressions rationnelles sont si maladroites par rapport à SNOBOL ! Maintenant que était un cours de programmation intéressante! Avec celui de Simula .
Ah les joies d'étudier à l'UNSW à la fin des années 70! (-:
la source
Pour PHP, "il est toujours sûr de faire précéder un caractère non alphanumérique par" \ "pour spécifier qu'il se représente." - http://php.net/manual/en/regexp.reference.escape.php .
Sauf si c'est un "ou '.: /
Pour échapper aux variables de modèle d'expression régulière (ou variables partielles) en PHP, utilisez preg_quote ()
la source
Savoir quand et quoi échapper sans tentatives est nécessaire pour comprendre précisément la chaîne de contextes traversés par la chaîne. Vous spécifierez la chaîne du côté le plus éloigné à sa destination finale qui est la mémoire gérée par le code d'analyse regexp.
Soyez conscient de la façon dont la chaîne en mémoire est traitée: si peut être une chaîne simple à l'intérieur du code, ou une chaîne entrée dans la ligne de commande, mais a pourrait être soit une ligne de commande interactive soit une ligne de commande indiquée dans un fichier de script shell, ou à l'intérieur d'une variable en mémoire mentionnée par le code, ou un argument (chaîne) via une évaluation plus approfondie, ou une chaîne contenant du code généré dynamiquement avec n'importe quelle sorte d'encapsulation ...
Chacun de ce contexte a assigné des caractères avec des fonctionnalités spéciales.
Lorsque vous voulez passer le caractère littéralement sans utiliser sa fonction spéciale (locale au contexte), c'est le cas où vous devez l'échapper, pour le contexte suivant ... qui pourrait avoir besoin d'autres caractères d'échappement qui pourraient également avoir besoin d'être échappé dans le (s) contexte (s) précédent (s). De plus, il peut y avoir des choses comme le codage de caractères (le plus insidieux est utf-8 car il ressemble à ASCII pour les caractères communs, mais peut éventuellement être interprété même par le terminal en fonction de ses paramètres afin qu'il puisse se comporter différemment, puis l'attribut de codage de HTML / XML, il est nécessaire de bien comprendre le processus.
Par exemple, une expression rationnelle dans la ligne de commande commençant par
perl -npe
, doit être transférée à un ensemble d' appels système exec se connectant en tant que canal que le fichier gère, chacun de ces appels système exec a juste une liste d'arguments qui ont été séparés par des espaces (non échappés), et éventuellement des tuyaux (|) et redirection (> N> N> & M), parenthèses, expansion interactive de*
et?
,$(())
... (tout ceci sont des caractères spéciaux utilisés par le * sh qui peuvent sembler interférer avec le caractère de l'expression régulière dans le contexte suivant, mais ils sont évalués dans l'ordre: avant la ligne de commande. La ligne de commande est lue par un programme comme bash / sh / csh / tcsh / zsh, essentiellement à l'intérieur de guillemets doubles ou de guillemets simples, l'échappement est plus simple mais il n'est pas nécessaire de citer une chaîne dans la ligne de commande car la plupart du temps l'espace doit être préfixé avec une barre oblique inverse et la citation est il n'est pas nécessaire de laisser disponible la fonctionnalité de développement pour les caractères * et?, mais cette analyse est aussi différente du contexte que dans les guillemets. Ensuite, lorsque la ligne de commande est évaluée, l'expression rationnelle obtenue en mémoire (pas comme écrite dans la ligne de commande) reçoit le même traitement qu'elle serait dans un fichier source. Pour l'expression rationnelle, il y a un contexte de jeu de caractères entre crochets [],l'expression régulière perl peut être citée par un grand ensemble de caractères non alphanumériques (par exemple m // ou m: / better / for / path: ...).Vous avez plus de détails sur les caractères dans d'autres réponses, qui sont très spécifiques au contexte d'expression rationnelle final. Comme je l'ai noté, vous mentionnez que vous trouvez l'échappement regexp avec des tentatives, c'est probablement parce que le contexte différent a un ensemble de caractères différent qui a confondu votre mémoire des tentatives (souvent la barre oblique inverse est le caractère utilisé dans ces différents contextes pour échapper à un caractère littéral au lieu de sa fonction ).
la source
https://perldoc.perl.org/perlre.html#Quoting-metacharacters et https://perldoc.perl.org/functions/quotemeta.html
Dans la documentation officielle, ces caractères sont appelés métacaractères. Exemple de citation:
la source
Pour Ionic (Typescript), vous devez doubler la barre oblique afin de scape les personnages. Par exemple (ceci correspond à certains caractères spéciaux):
Faites attention à ces
] [ - _ . /
personnages. Ils doivent être doublés. Si vous ne le faites pas, vous allez avoir une erreur de type dans votre code.la source