2010-02-22 4 views

Répondre

3

Qu'en est-il quelque chose comme ceci:

$str = <<<STR 
{{Title|Open 
Bla-bla-bla 
}} 
STR; 

$matches = array(); 
if (preg_match("/^\{\{([^\|]+)\|([^\n]+)(.*)\}\}$/s", $str, $matches)) { 
    var_dump($matches); 
} 

Il vous obtenez:

array 
    0 => string '{{Title|Open 
Bla-bla-bla 
}}' (length=28) 
    1 => string 'Title' (length=5) 
    2 => string 'Open' (length=4) 
    3 => string ' 
Bla-bla-bla 
' (length=14) 

Ce qui signifie que, après avoir utilisé trim sur $matches[1], $matches[2] et $matches[3], vous obtenez ce que vous avez demandé :-)


Explication de la regex:

  • correspondant depuis le début de la chaîne: ^
  • deux { caractères, qui doivent être échappé, car ils ont une signification particulière
  • tout ce qui est pas un |, au moins une fois: [^\|]+
    • entre () il est capturé - retourné comme la première partie du résultat
    • | doit être échappé aussi.
  • un caractère | qui doit être échappé.
  • Tout ce qui est pas une ligne-break, au moins une fois: [^\n]+
    • entre () il est capturé trop - deuxième partie du résultat
  • .* pratiquement « tout » anynumber fois
    • entre () il est capturé trop - troisième partie du résultat
  • et, enfin, deux }(échappèrent aussi)
  • et une fin de chaîne: $

Et notez l'expression rationnelle a s(dotall) modificateur; voir Pattern Modifiers, à ce sujet.

+0

+1 pour expliquer l'expression rationnelle en détail! –

3
$string = "{{Title|Open 
Bla-bla-bla 
}}"; 

preg_match('/^\{\{([^|]+)\|(.*?)[\r\n]+(.*?)\s*\}\}/', $string, $matches); 
print_r($matches); 
0

En Perl:

/\{\{   # literal opening braces 
(.*?)  # some characters except new line (lazy, i. e. as less as possible) 
\|   # literal pipe 
(.*?)  # same as 2 lines above 
\n   # new line 
([\s\S]*?) # any character, including new line (lazy) 
\}\}/x;  # literal closing braces 

Faire une solution plus précise dépend de ce que les règles exacte que vous voulez pour l'extraction de vos champs.

Questions connexes