web-dev-qa-db-fra.com

Quels caractères littéraux doivent être échappés dans une regex?

Je viens d'écrire une expression régulière à utiliser avec la fonction php preg_match qui contient la partie suivante:

[\w-.]

Pour faire correspondre n'importe quel caractère Word, ainsi qu'un signe moins et le point. Bien que cela semble fonctionner dans preg_match, j'ai essayé de le mettre dans un utilitaire appelé Reggy et il se plaint de "Plage vide dans la classe char" . Les essais et les erreurs m’ont appris que ce problème était résolu en échappant au signe moins, en transformant la regex en

[\w\-.]

Puisque l'original semble fonctionner en PHP, je me demande pourquoi je ne devrais pas ou non échapper au signe moins, et - puisque le point est aussi un caractère ayant une signification en PHP - pourquoi je n'en aurais pas besoin pour échapper au point. Est-ce que l'utilitaire que j'utilise est juste idiot, fonctionne-t-il avec un autre dialecte de la regex ou est-ce que ma regex est vraiment incorrecte et suis-je simplement chanceux que preg_match me laisse m'en tirer?

23
Pelle ten Cate

Dans de nombreuses implémentations regex, les règles suivantes s'appliquent:

Les méta-caractères d'une classe de caractères sont:

  • ^ (négation)
  • - (plage)
  • ] (fin du cours)
  • \ (caractère d'échappement)

Donc, ils devraient tous être évités. Il y a quelques cas de coin cependant:

  • - n'a pas besoin d'être échappé s'il est placé au tout début ou à la fin de la classe ([abc-] ou [-abc]). Dans de nombreuses implémentations de regex, il n’est pas non plus nécessaire d’échapper s’il est placé directement après une plage ([a-c-abc]) ou une classe de caractères à caractères abrégés ([\w-abc]). C'est ce que vous avez observé
  • ^ n'a pas besoin d'être échappé quand il s'agit de not au début de la classe: [^a] signifie tout caractère sauf a, et [a^] correspond à a ou ^, ce qui correspond à: [\^a]
  • ] n'a pas besoin d'être échappé s'il s'agit du seul caractère de la classe: []] correspond au caractère ]
58
Bart Kiers
[\w.-]
  • le . signifie généralement que n'importe quel caractère, mais entre [] n'a pas de signification particulière
  • - entre [] indique une plage sauf si elle est échappée ou que le premier ou le dernier caractère entre []
6
bw_üezi

Bien qu'il existe effectivement certains caractères doivent être échappés dans une expression rationnelle , vous ne vous posez pas de question sur l'expression rationnelle, mais sur la classe de caractère. Où le symbole tiret est spécial.

au lieu de l’échapper, vous pouvez le mettre à la fin du cours, [\w.-]

4
Your Common Sense

L'arrêt complet perd sa signification dans la classe de caractères.

Le - a une signification particulière dans la classe de caractères. S'il n'est pas placé au début ou à la fin des crochets, il doit être échappé. Sinon, il s'agit d'une plage de caractères (A-Z).

Vous avez déclenché un autre cas particulier cependant. [\w-.] fonctionne car \w ne dénote pas un seul caractère. En tant que tel, PCRE ne peut éventuellement pas créer une plage de caractères. \w est une classe de symboles éventuellement non cohérente. Par conséquent, aucun caractère de fin ne peut être utilisé pour créer la plage Z till .. L'arrêt complet . précéderait également le premier caractère ascii a auquel \w pourrait correspondre. Il n'y a pas de plage constructible. Dorénavant, - a travaillé sans vous échapper.

3
mario

Si vous utilisez php et avez besoin d'échapper à des caractères spéciaux de regex, utilisez simplement preg_quote:

Un exemple de php.net :

<?php
// In this example, preg_quote($Word) is used to keep the
// asterisks from having special meaning to the regular
// expression.

$textbody = "This book is *very* difficult to find.";
$Word = "*very*";
$textbody = preg_replace ("/" . preg_quote($Word, '/') . "/",
                          "<i>" . $Word . "</i>",
                          $textbody);
?>
0
RedClover