2010-12-09 3 views
1

J'ai le texte suivant exempleproblème avec l'ordre correspondant à une expression régulière en PHP

The quick brown {fox} jumps over the lazy {dog} 

je dois correspondre à une chaîne entre {} qui peut se produire plusieurs fois dans le texte.
J'ai essayé le code suivant, mais il ne fonctionne pas correctement

<?php 

$matches = array(); 

$string = "The quick brown {fox} jumps over the lazy {dog}"; 

preg_match("/\{(.*)\}/",$string,$matches); 

print_r($matches); 

?> 

et c'est ce que je reçois

Array 
(
    [0] => {fox} jumps over the lazy {dog} 
    [1] => fox} jumps over the lazy {dog 
) 

je me attends obtenir

Array 
(
    [0] => {fox} jumps over the lazy {dog} 
    [1] => fox 
    [2] => dog 
) 

Alors, comment puis-je forcer PHP pour faire correspondre le "}" le plus proche au lieu de faire correspondre le dernier?

Répondre

3

Votre regex existante a .* qui est avide et essaie de consommer autant que possible. Pour corriger cela, vous devez faire la regex non gourmand en ajoutant un ? à la fin comme:

.*? 

Sinon, vous pouvez également utiliser [^}]* en place de .*.

Et puisque vous voulez que tous les matches, vous devez utiliser preg_match_all

See it

+0

Cela fonctionne très bien. Pourriez-vous s'il vous plaît expliquer l'utilisation de? dans ce cas ? Cette utilisation est-elle documentée? – AssemblerGuy

+0

Le? est une caractéristique standard des expressions régulières: voir http://www.regular-expressions.info/repeat.html pour plus de détails sur la gourmandise/la paresse –

0

Par défaut, votre regexp est exécuté en mode gourmand. Tu as besoin d'être insupportable. Utilisez le commutateur/U ou la suggestion de codaddict de *. pour rendre cette partie de l'expression non confiante

0

Par défaut, les expressions sont gourmandes, c'est-à-dire qu'elles essaient d'obtenir les correspondances les plus longues possibles. Vous pouvez rendre une expression non confuse avec le drapeau U:

preg_match('/\{(.*)\}/U', $string, $matches); 
Questions connexes