2013-02-08 4 views
3

J'ai trouvé l'expression rationnelle suivante dans le code PHP du Textism Textile:Je ne comprends pas ce textile Regex

/\b ?[([]TM[])]/i 

Je me considère être expérimenté dans la lecture regexes mais celui-ci est un mystère pour moi. Le début est facile, mais je ne comprends pas pourquoi il y a deux classes de caractères vides à l'intérieur d'une classe de caractères déjà ouverte [[][]]?

Quelqu'un peut-il faire la lumière sur ce problème?

+1

Ce regex ne compile pas ... – lonesomeday

+2

Le regex compile correctement. –

+1

@lonesomeday, tout dépend de la langue/de l'outil que vous utilisez. C'est un PCRE valide. Vois ma réponse. –

Répondre

9

Il est un est un peu cryptique ...

Voici ce que cela signifie:

/  # start regex pattern 
\b # word boundary 
? # an optional space 
[([] # char class: either '(' or '[' 
TM # literal 'TM' 
[])] # char class: either ']' or ')' 
/ # end regex pattern 
i  # match case insensitive 

Quelques choses à noter:

  • dans une classe de caractères, [ n'est pas spécial et ne doit pas être échappé ([([] est donc valide!)
  • à l'intérieur d'une classe de caractères, le premier caractère, éventuellement un caractère spécial, n'a pas besoin d'être échappé ([])] est à cet effet valide: ] besoins ne peut échapper!)

Pour résumer, il correspond "TM" insensible à la casse entouré soit [ ou ( et ] ou ) (ils ne doivent pas nécessairement être apparié: "[TM)" sera apparié dans la plupart des cas). Je dis dans la plupart des cas, parce que \b ? causera "[tm)" à exclure des matches de la démo ci-dessous car il est précédé par ". " qui ne correspond pas à \b ?:

<?php 
preg_match_all(
    '/\b ?[([]TM[])]/i', 
    "... [tm) foo (TM) bar [TM] baz (tm] ...", 
    $matches 
); 
print_r($matches); 
?> 
/* 
Array 
(
    [0] => Array 
     (
      [0] => (TM) 
      [1] => [TM] 
      [2] => (tm] 
     ) 

) 
*/ 
+0

mais ne devrait pas '(' et ')' être échappé? –

+0

Merci pour une explication claire. Il semble que cela ne fonctionne que pour les machines Regex compatibles Perl. – micxer

+0

@Krishna Pas besoin d'échapper à '(' et ')' dans la classe de caractères. –

2

EDIT: ] semble être autorisé en tant que premier caractère d'une classe de caractères si l'expression régulière suit la syntaxe POSIX des expressions régulières. Voir http://www.regular-expressions.info/posixbrackets.html. En PHP, les fonctions eregs_ utilisent POSIX tandis que les fonctions preg_ utilisent la nouvelle version de PCRE qui n'autorise pas cette construction.

Ainsi, à la condition saveur POSIX:

[([] 

est une classe de caractères comprenant (et [et

[])] 

est un autre composé de] et). La plupart des moteurs d'expressions rationnelles nécessiteraient l'écriture de la seconde classe de caractères

[\])] 

à la place.

+0

Mais ne devrait pas montrer une erreur. Le 2ème dernier ']' pourrait être considéré comme celui fermant le prevoius '['? En Java, cette regex est erronée. –

+0

Juste, exactement ce qui m'a dérouté. – micxer

+0

Vous semblez avoir raison. L'expression rationnelle semble invalide selon Javascript aussi. –