2009-12-07 4 views
2

Juste besoin de voir si un paragraphe contient un "mot d'arrêt", les mots d'arrêt sont dans un tableau ci-dessous.Encore un peu difficile preg_match

J'ai eu la formule comme:

$pattern_array = array("preheat", "minutes", "stir", "heat", "put", "beat", "bowl", "pan"); 

    foreach ($pattern_array as $pattern) { 
     if (preg_match('/'.$pattern.')/i', $paragraph)) { 
     $stopwords = 1; 
     } 
    } 

Ce qui fonctionne assez bien, mais pour des mots courts comme un mot « pan » comme « panko » est identifié comme un mot d'arrêt. L'expression regex doit donc être précédée d'un espace ou être le début d'une nouvelle ligne et se terminer par un arrêt complet/espace/virgule/(autres objets non-caractère).

Comment puis-je dire à php de quitter la boucle dès qu'un mot d'arrêt est identifié?

Merci les gars, ralentir l'apprentissage regex comme je vais!

+1

En ce qui arrêter la boucle quand vous trouvez un match, vérifier php.net/break –

Répondre

4

Utilisez \b(preheat|minutes|stir|heat|put|bowl|pan)\b comme regex. De cette façon, vous n'avez besoin que d'une regex (aucune boucle nécessaire), et en utilisant les assertions de limite de mots \b, vous vous assurez que seuls les mots entiers correspondent.

+0

Ok Ive utilisé cette approche (le tout dans une regex pas le \ b) et j'ai été averti des problèmes de performance si la quantité d'éléments dans la regex devient trop grande. Combien d'articles seraient trop nombreux? – bluedaniel

+0

Difficile à dire. Je suppose que vous êtes coincé avec des regex si vous voulez faire correspondre les limites des mots, et boucler sur une multitude d'expressions régulières est probablement plus lent que d'avoir une seule regex. Vous pouvez faire quelques optimisations comme '\ b (p (?: Réchauffer | ut | an) | st (?: Ir | ove) | etc.) \ B' afin que le moteur regex puisse ignorer une correspondance partielle après avoir trouvé que le premier le ou les caractères ne correspondent pas, mais il vaut mieux essayer d'abord avant d'optimiser inutilement. –

+0

Hmm c'est une approche intéressante, c'est définitivement un cas de faire fonctionner une application comme prévu et ensuite d'optimiser les petits segments de choses. Je vais essayer plus tard et pour votre suivi, j'accepterai votre réponse. Bravo Tim. – bluedaniel

2

N'avez pas essayé ceci, mais \b devrait être le groupe de caractères que vous recherchez. De l'PHP manual:

\b word boundary 

Votre code serait alors ressembler à quelque chose comme ceci:

$pattern_array = array("preheat", "minutes", "stir", "heat", "put", "beat", "bowl", "pan"); 

foreach ($pattern_array as $pattern) { 
    if (preg_match('/\b'.$pattern.'\b/i', $paragraph)) { // also removed the ')' 
    $stopwords = 1; 
    break; // to exit the loop 
    } 
} 

Edit: semble que les gens sont mieux lotis en utilisant \ b, donc changé cette conséquence

+0

il ne correspondra pas à la fin de la chaîne de sujet. – SilentGhost

+0

ou le début d'ailleurs – SilentGhost

+0

a changé le code pour utiliser '\ b', merci pour les commentaires :-) –

2

vous devez ajouter \b (qui signifie limite de mot) à votre regex comme ceci:

'/\b'.$pattern.'\b/i' 

Vous semblez avoir une faute de frappe dans votre code, soit parce que vous avez un crochet de fermeture littéral (et ne correspondent pas à certaines parties des mots), soit parce que vous avez un crochet de fermeture ouvert.

+0

oui désolé, c'est une faute de frappe d'un test de code précédent – bluedaniel

2

1. Vous pouvez utiliser "\ b" pour vérifier les limites de mots. Une limite de mot est définie comme la frontière entre un caractère de mot et un caractère de non-mot. les mots-caractères sont des lettres, des chiffres et des traits de soulignement.

2. Vous pouvez le faire d'un seul coup, en utilisant « | »:

$stopwords = preg_match('/\\b(preheat|minutes|stir|heat|..other words..|pan)\\b/i', $paragraph) 
+0

Ok Ive a utilisé cette approche (l'expression rationnelle tout-en-un pas le \ b) et j'ai été averti des problèmes de performance si la quantité d'éléments dans la regex devenait trop grande. Combien d'articles seraient trop nombreux? – bluedaniel