2010-10-30 6 views
1

je la chaîne suivante:Quel est le problème avec cette regex?

<?php 
$string = '<meta name="Keywords" lang="fr" content="ecole commerce, 
apres bac, ecole management, ecole de management, écoles de commerce, 
école de management, classement ecole de commerce, ecole commerce paris, 
ecole superieure de commerce, concours ecole commerce, hec, esc, prepa, 
forum ecole commerce, avis ecole commerce" /><meta name="description" 
content="Tout pour s\'informer et échanger sur les écoles de commerce 
et de management, les concours, les classements, la prépa... Des 
témoignages et un forum pour faire le meilleur choix" /><meta 
name="robots" content="all" />'; 
?> 

et j'essaie d'obtenir que la "description" méta de lui avec cette expression regex:

<?php 
echo preg_replace('/(?:.*)name\="description" content\="(.*)"(?:.*)/i', 
                    '$1', $string); 
?> 

mais ce que je reçois est:

Tout pour s'informer et échanger sur les écoles de commerce et de management, 
les concours, les classements, la prépa... Des témoignages et un forum 
pour faire le meilleur choix" /><meta name="robots" content="all 

Alors, pourquoi le supplément " /><meta name="robots" content="all?!

ps: il n'y a pas de sauts de ligne dans le code, je les ajoutais pour une meilleure lisibilité ...

+1

Il essaye d'analyser HTML, c'est ce qui ne va pas avec. http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – You

Répondre

1

Ne pas utiliser regexps cupides pour elle, cela fonctionne:

<?php echo preg_replace('/(?:.*)name\="description" content\="(.*?)"(?:.*)/i', '$1', $string); ?> 
2

Vous devez également ajouter l'option U (Ungreedy) à votre regexp. Dans ce cas, elle correspond à la dernière « de votre chaîne, qui est la raison pour laquelle vous obtenez la partie tag

preg_replace('/(?:.*)name\="description" content\="(.*)"(?:.*)/iU', '$1', $string); 

Remarque Vous pouvez également le remplacer par quelque chose comme ceci:.

preg_replace('/(?:.*)name\="description" content\="([^"]*)"/i', '$1', $string); 

[^ » ] signifie "tout ce qui n'est pas une double citation". Le dernier (?:. *) Est également inutile. J'apprécie aussi d'utiliser preg_match avec un troisième argument quand on veut faire correspondre quelque chose sans le remplacer. Au fond, je ferais ce que vous voulez faire comme ceci:

$var = array(); 
preg_match('/name\="description" content\="([^"]*)"/iU', $string, $var); 

$ var [1] contient votre chaîne si l'expression régulière a trouvé un match.

+0

PS: Le premier '(?:. *)' est également inutile; – NikiC

1

Un idiome que j'utilise pour éviter regexes cupides est d'utiliser une inverse de modèle de recherche pour les enceintes (qui est [^"] si quelque chose est censé être entouré de citations). Plus fiable pour les cas de pointe avant-gardistes:

/content="([^"]*)"/i 
+0

Et aussi potentiellement plus efficace. – bobince

0

/: - (.) (?. ) nom contenu \ = "description" \ = "> < --C'est ce qui correspond à la substance supplémentaire que vous ne veulent pas/ne vous attendez pas correspondre

/(: ?.) nom \ = "description" content \ = "(.) ->" < --C'est ce qui correspond à la citation après. le mot «tous»

Vous voulez que l'expression régulière cesse de correspondre plus tôt plutôt que plus tard, d'où la nécessité de le mettre dans un mode de fonctionnement peu gourmand (ce que d'autres affiches ont dit).

Questions connexes