2009-10-29 6 views
4

d'abord, il s'agit d'utiliser preg.regex correspond au groupe répétitif {0,2} ou {0,4} mais {0,3} ne correspond pas à

chaîne Je suis en train de faire correspondre:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa b c d xp 

Mon regex et leurs matches:

(\S*\s*){0,1}\S*p = "d xp" 
(\S*\s*){0,2}\S*p = "c d xp" 
(\S*\s*){0,3}\S*p = NO MATCH (expecting "b c d xp" 
(\S*\s*){0,4}\S*p = entire string 
(\S*\s*){0,5}\S*p = entire string 

Bizarrement, si je retire un "a" cela fonctionne. En outre, (\S*\s*){0,3}\Sp ou (\S*\s){0,3}\S*p tous deux fonctionnent. Est-ce que quelqu'un peut expliquer pourquoi le troisième cas n'aboutit à aucune correspondance au lieu de "b c d xp"?

TIA!

+0

'm/(\ S * \ s *) {0,3} \ S * p /' fonctionne sur votre chaîne de test http: //regex.powertoy.org ... – beggs

+0

BTW. .. un besoin spécifique d'utiliser '*' et non '+'? Je reçois les mêmes allumettes que tu cherches avec beaucoup moins de sondes? Par exemple 'm/(\ S + \ s +) {0,3} \ S + p /' correspond 'bcd xp' dans 3081 sondes alors que' m/(\ S * \ s *) {0,3} \ S * p/'produit la même correspondance dans 1200222 sondes! – beggs

+0

Je signalerais cela comme un bug. Il correspond à PCRE (version 7.8), mais ne correspond pas à PHP 5.2.6 ou 5.3.0 (qui utilise PCRE pour ses fonctions preg_ matching). – newacct

Répondre

2

preg_last_error() renvoie PREG_BACKTRACK_LIMIT_ERROR, donc l'augmentation de la limite de retour arrière devrait probablement résoudre le problème. Essayez

ini_set('pcre.backtrack_limit', 500000); 
+0

Aha, quelqu'un qui connaît la vraie réponse ... – DigitalRoss

+0

génial. Merci beaucoup! Cela me rendait fou. – robgmills

7

Bonne question.

J'ai essayé une autre langue qui a également la syntaxe Perl RE, Ruby, et il est revenu la chaîne attendue:

$ irb 
>> s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa b c d xp' 
=> "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa b c d xp" 
>> s[/(\S*\s*){0,3}\S*p/] 
=> "b c d xp" 

Cela m'a fait penser que vous avez trouvé un bug d'interprète ...

Mais nous maintenant savoir que

  • votre RE était correcte, tout comme vos attentes de ses résultats
  • PHP a une limite backtracks, et problème était votre expression a atteint la limite. Ruby ne vérifie pas, ou a une limite différente.
Questions connexes