2009-05-14 9 views
0

demo:php non gourmand problème regex

$str = 'bcs >Hello >If see below!'; 
$repstr = preg_replace('/>[A-Z0-9].*?see below[^,\.<]*/','',$str); 
echo $repstr; 

Ce que je veux que ce petit programme de sortie est « bcs> Bonjour », mais en fait, il est seulement « bcs »

Quel est le problème avec mon modèle ?

+0

Votre question n'a pas de sens étant donné votre extrait de code. Votre déclaration remplace le motif avec rien. Votre réponse suggère que vous voulez le remplacer par quelque chose. – cletus

+0

Le programme fait ce que vous lui avez demandé de faire. Ce n'est pas clair ce que vous voulez obtenir. Donne un autre exemple. – jbasko

+0

C'est quelque chose en rapport avec la regex non gourmande, je pense que c'est assez clair, pourquoi pas? – omg

Répondre

0

Pourquoi ne pas vous écrivez comme ceci:

$str = 'bcs >Hello >If see below!'; 
$repstr = preg_replace('/>If see below[^,\.<]*/','',$str); 
echo $repstr; 
+0

parce que ce que je veux est le premier caractère ou numéro en majuscule après> – omg

0

Cela pourrait être une bonne alternative à ce que vous avez. Le problème avec votre expression rationnelle est qu'au lieu de sélectionner ce que vous voulez, vous sélectionnez ce que vous ne voulez pas et le remplacez par une chaîne vide. La meilleure approche, à mon avis, est de sélectionner ce que vous voulez, c'est ce que fait le code ci-dessous. Ce que vous finissez par est ce qui est ce qui correspond au premier sous-modèle sinon vous récupérez votre chaîne.

$str = 'bcs >Hello >If see below!'; 
$repstr = preg_replace('/^([\w]+ >[\w]+).*?see below.*?$/i', '$1', $str); 
var_dump($repstr); 

J'espère que cela aide.

+0

Désolé, ce que je veux faire est exactement remplacer: à partir de "premier caractère majuscule ou numéro après>" fin avec "voir ci-dessous [^, \. < ] * " pour vider. – omg

4

Je pense que le problème est que vous interprétez mal comment un quantificateur non gourmand agit. Une fois qu'il fonctionne, oui, il s'arrête plus tôt qu'il ne le ferait autrement. Mais ce n'est pas au courant de ce qui vient avant (ou potentiellement le texte qui vient plus tard, soit). Il est seulement concerné par sa position actuelle. Par conséquent, l'expression régulière que vous avez affichée correspondra tous:

">Hello >If see below!" 

Voyons voir comment cela fonctionne:

/>[A-Z0-9].*?see below[^,\.<]*/ 

Le regex recherche d'abord « > » dans « bcs> Bonjour> Si voir ci-dessous! ", et trouve le premier, qui est celui juste avant" Bonjour ". Ok, nous allons vérifier la partie suivante de l'expression:

[A-Z0-9] 

Le caractère suivant est un H, qui correspond au motif [A-Z0-9]. Encore bon! Suivant:

.*? 

Maintenant, nous correspondent tous les caractères non-retour à la ligne jusqu'à ce que nous arrivons à la première instance pour faire correspondre les expressions restantes de "voir ci-dessous [^ ,. <] *". Si nous n'avions utilisé qu'un simple quantificateur glouton, nous pourrions faire correspondre plusieurs cas de "voir ci-dessous [^, <] *" jusqu'à ce que nous ayons fait correspondre le dernier possible. (Donc, si votre chaîne avait continué, et qu'il y avait un autre texte correspondant à ce modèle, cela l'aurait également capturé) Le quantificateur non-gourmand ne signifie pas que votre motif entier retournera le plus petit résultat possible de toutes les correspondances possibles dans la chaîne. Il dicte juste comment ce caractère particulier correspond aux fonctions.

Vous pouvez essayer le modèle suivant alors:

/>[A-Z0-9][^>]*?see below[^,\.<]*/ 

Espérons que cela efface ça!

+0

Merci pour votre réponse, mais cela ne fonctionnera pas pour moi. Parce que cela ne fonctionnera pas dans ce cas: $ str = 'bcs <> Bonjour <> Si
voir ci-dessous!'; Je veux avoir 'bcs <> Bonjour <' après le traitement. – omg

+0

Vous pourriez essayer d'élaborer plus en détail le contexte de votre question, et vous pourriez obtenir de meilleures réponses. – patjbs

+0

Voici la solution: $ str = 'bcs <> Bonjour <> Si

voir ci-dessous!'; $ repstr = preg_replace ('/> [A-Z0-9] [^>] * (> [^ A-Z0-9] *) * voir ci-dessous [^, \. <] * /', '', $ str); echo $ repstr; Merci de votre attention sur ce problème :) – omg