Dans une expression régulière, quels caractères doivent s'échapper?

23

En général, quels caractères d'une expression régulière doivent s'échapper?

Par exemple, ce qui suit n'est pas syntaxiquement correct:

echo '[]' | grep '[]'
grep: Unmatched [ or [^

Ceci, cependant, est correct sur le plan statistique:

echo '[]' | grep '\[]'
[]

Existe-t-il une documentation sur les caractères qui devraient être échappés dans une expression régulière et ceux qui ne devraient pas?

LanceBaynes
la source

Réponses:

12

Cela dépend de l'application. Dans votre exemple, [doit être cité comme argument pour grepmais pasecho .

Pour le shell (d'après les spécifications POSIX ):

La citation est utilisée pour supprimer la signification spéciale de certains caractères ou mots dans le shell. La citation peut être utilisée pour préserver la signification littérale des caractères spéciaux dans le paragraphe suivant, empêcher les mots réservés d'être reconnus comme tels et empêcher l'expansion des paramètres et la substitution de commandes dans le traitement ici-document (voir Here-Document).

La candidature doit citer les caractères suivants s'ils veulent se représenter:

|  &  ;  <  >  (  )  $  `  \  "  '  <space>  <tab>  <newline>

et les éléments suivants peuvent devoir être cités dans certaines circonstances. Autrement dit, ces caractères peuvent être spéciaux selon les conditions décrites ailleurs dans ce volume de IEEE Std 1003.1-2001:

*   ?   [   #   ˜   =   %

Les différents mécanismes de citation sont le caractère d'échappement, les guillemets simples et les guillemets doubles. Le document ici représente une autre forme de citation; voir ici-document.

Des programmes spécifiques (utilisant des expressions régulières, perl, awk) pourraient avoir des exigences supplémentaires sur l'échappement.

Matteo
la source
8

Chaque application aura son propre jeu de caractères «spéciaux». Le problème que vous avez rencontré concernait greppas le shell. Pour quels caractères doivent être cités grep, lisez la section de la page de manuel sur "EXPRESSIONS RÉGULIÈRES".

Pour le shell, les caractères qui doivent être cités sont:

;'"`#$&*?[]<>{}\

et n'importe quel espace.

Selon le shell, d'autres caractères peuvent également devoir être cités:

!^%

Regardez sous "SHELL GRAMMAR" sur la page de manuel du shell.

Arcege
la source
Dans certains shells avec expansion d'historique ( bashinclus), !est toujours développé entre guillemets doubles, seuls les guillemets simples arrêteront son expansion (ou désactiveront l'option shell).
Chris Down du
]ne doit pas être cité, [pas toujours. Je n'ai trouvé aucune référence à {et}
Matteo
8

Il existe plusieurs types d'expressions régulières et l'ensemble de caractères spéciaux dépend du type particulier. Certains d'entre eux sont décrits ci-dessous. Dans tous les cas, les caractères spéciaux sont échappés par une barre oblique inverse \. Par exemple, pour correspondre à [vous écrivez à la \[place. Alternativement, les caractères (sauf ^) pourraient être échappés en les enfermant entre crochets comme un par un [[].

Les caractères qui sont spéciaux dans certains contextes comme ^spécial au début d'une (sous-) expression peuvent être échappés dans tous les contextes.

Comme d'autres l'ont écrit: dans le shell si vous ne placez pas l'expression entre guillemets simples, vous devez également échapper les caractères spéciaux pour le shell dans l'expression régulière déjà échappée. Exemple: au lieu de '\['vous pouvez écrire \\[(alternativement: "\["ou "\\[") dans des shells compatibles Bourne comme bash mais c'est une autre histoire.

Expressions régulières de base (BRE)

  • POSIX: Expressions régulières de base
  • Commandes: grep,sed
  • Caractères spéciaux: .[\
  • Spécial dans certains contextes: *^$
  • Échapper une chaîne: "$(printf '%s' "$string" | sed 's/[.[\*^$]/\\&/g')"

Expressions régulières étendues (ERE)

  • POSIX: Expressions régulières étendues
  • Commandes:, grep -EGNU sed -r:, * BSD:sed -E
  • Caractères spéciaux: .[\(
  • Spécial dans certains contextes: *^$)+?{|
  • Échapper une chaîne: "$(printf '%s' "$string" | sed 's/[.[\*^$()+?{|]/\\&/g')"
pabouk
la source
3

greputilise BRE comme méthode d'expression régulière. Il y a une bonne documentation sur elle ici , un aperçu général serait « échapper à un caractère spécial ou métacaractère pour obtenir son littéral, échapper pour créer des séquences d'échappement ( \n, \r, etc.) », bien que ce soit pas toujours vrai, par exemple, vous devez s'échapper (et )obtenir leur signification particulière (référence).

Chris Down
la source
0

Le shell peut transformer la ligne de commande avant l'exécution de la commande. Le shell et greppeut utiliser des guillemets pour supprimer la signification spéciale de certains caractères. Néanmoins, les grepobus ont différents caractères spéciaux. De plus, les caractères spéciaux non échappés qui ne résultaient pas d'une extension existante sont supprimés, avant l'exécution de la commande, par le shell.

echo '[]' | grep '[]'

Le shell transmet l'argument []à grepet il est analysé comme une expression de crochet mal formée par grep.

echo '[]' | grep \[]

Ci-dessus, nous pouvons voir un cas similaire. La barre oblique inverse est supprimée et []est transmise comme argument à grep. grepreconnaît une expression de crochet mal formée.

echo '[]' | grep '\[]'

Enfin, dans ce cas, les guillemets sont supprimés par le shell et \[]transmis comme argument à grepmais, dans ce cas spécifique ¹, \[est interprété par grepcomme une parenthèse littérale. Des citations sont nécessaires pour empêcher l'interprétation de la barre oblique inverse comme un caractère spécial par le shell.


¹ Spécification POSIX .

Fólkvangr
la source