2011-11-22 4 views
5

Je voudrais utiliser une sorte d'opérateur logique "AND" dans mon expression régulière. Je essayé ceci:Opérateur logique ET avec expression rationnelle php

(?=exp1)(?=exp2) 

Mais en PHP ?= ne fonctionne pas et besoin d'écrire mon programme en langage PHP. Y a-t-il une autre méthode? L'expression doit correspondre si toutes les conditions sont présentes et dans n'importe quel ordre. Je ne veux pas écrire toutes les permutations comme:

(exp1)(exp2)(exp3)|(exp1)(exp3)(exp2)|.... 
+0

Je pense que vous aurez besoin de diviser les expressions rationnelles – DiogoDoreto

+4

Ummm. php prend en charge '(? = ...)': http://php.net/manual/en/regexp.reference.assertions.php –

Répondre

9

PHP supporte les expressions lookahead. Cependant, vous ne les utilisez probablement pas correctement.

En supposant que vous voulez faire correspondre une chaîne qui contient les trois foo, bar et baz, vous avez besoin du regex

^(?=.*foo)(?=.*bar)(?=.*baz) 

Cela renverra un match pour les cordes foobarbaz ou barbazfoo etc. Cependant, ce match sera la chaîne vide (parce que les lookaheads ne consomment aucun caractère). Si vous voulez que le regex pour retourner la chaîne elle-même, utilisez

^(?=.*foo)(?=.*bar)(?=.*baz).* 

qui sera ensuite correspondre à la chaîne entière si elle remplit les trois critères.

Je voudrais simplement utiliser

if (preg_match('/^(?=.*foo)(?=.*bar)(?=.*baz)/s', $subject)) { 
    # Successful match 
} else { 
    # Match attempt failed 
} 

Prenez note que cela correspond aussi une chaîne comme foonly bartender bazooka. Si vous ne voulez pas que (ne permettant permutations pures d'un chacun des trois expressions), vous pouvez le faire avec un petit truc:

^(?:foo()|bar()|baz()){3}\1\2\3$ 

matchs foobarbaz, foobazbar, barfoobaz, barbazfoo, bazfoobar et bazbarfoo (et rien d'autre). Le «truc» est inspiré par l'excellent livre de Jan Goyvaerts et Steven Levithan, "Regular Expressions Cookbook" (p. Il fonctionne comme suit:

  • Chaque pièce détachée (foo etc.) est suivi par un groupe de capture vide () qui correspond toujours si la partie requise a été adaptée.
  • Ainsi, si les trois parties requises ont été reconnues, les trois groupes de capture vides ont été appariés.
  • Les références arrières suivantes ne réussissent que si chacun des groupes de capture a participé à la correspondance.
  • Si la chaîne est foobarbar, la partie (?:foo()|bar()|baz()){3} aura correspondu, mais \3 échoue, de sorte que la regex globale échoue.
  • Si, cependant, tous les trois ont participé à la correspondance, \1\2\3 parvient à correspondre à la fin de la chaîne car chacun des groupes de capture ne contient que la chaîne vide.
+0

Bonne réponse complète. +1 – FailedDev

+0

@tim pourriez-vous fournir des ressources ou des informations supplémentaires à ce sujet? Je n'ai jamais vu quelque chose comme foo() | bar() | baz() auparavant. – bozdoz

+0

Je suppose, ce que je demande est quelle est la signification des parenthèses vides? – bozdoz

1

En plus de @ réponse Tim:

(?=exp1)(?=exp2) 

Cela ne peut jamais être vrai.Vous dites en anglais: assurez-vous que le texte suivi ici est exp1 et assurez-vous que le texte suivi ici est exp2. Pas du tout c'est vrai. Cela ne correspondra jamais.