2010-02-28 7 views
3

Tenir compte des chaînes suivantes:problème (dé) RegExp avide

1: cccbbb 

2: cccaaabbb 

Je voudrais finir avec sont matchs comme celui-ci:

1: Array 
(
    [1] => 
    [2] => bbb 
) 

2: Array 
(
    [1] => aaa 
    [2] => bbb 
) 

Comment puis-je correspondre à la fois dans un RegExp?
Voici mon essai:

#(aaa)?(.*)$# 

J'ai essayé de nombreuses variantes de modifications cupides et ungreedy mais il ne fonctionne pas. Dès que j'ajoute le '?' tout est égalé dans [2]. Faire [2] ungreedy n'aide pas.

Mon RegExp fonctionne comme prévu si j'omettent le « ccc », mais je dois permettre à d'autres personnages au début ...

+0

Pouvez-vous spécifier la deuxième partie mieux que juste avec '. *'? Peut-être avec 'b *'? – Gumbo

+0

Malheureusement non, je sais juste que le premier 'aaa' devrait correspondre dans' [1] ' –

+0

Et la partie avant' aaa'? – Gumbo

Répondre

3
/(aaa)?((.)\3*)$/ 

Il y aura un supplément [3] cependant. Je ne pense pas que ce soit un problème.

+0

Cela semble fonctionner! Cela vous dérangerait-il d'expliquer ce que fait la partie '(.) \ 3 *'? –

+0

@samy: '(.)' Correspond à n'importe quel caractère (sauf '\ n'). Il y a 3 parenthèses de capture ici, et '(.)' Est le 3ème. La partie '\ 3 *' signifie zéro ou plus "stuff" qui est identique à la 3ème correspondance. Donc, fondamentalement '(.) \ 3 * 'signifie un ou plusieurs caractères arbitraires mais identiques. – kennytm

+0

J'ai juste compris que ce n'est pas non plus. 'bbb' peut contenir des caractères différents. 'bbb' était problaby pas un bon exmaple. –

0

Voici une manière non-regex. rechercher et diviser sur "aaa" si trouvé, puis stocker le reste du côté droit de "aaa" dans le tableau.

$str="cccaaabbb"; 
if (strpos($str,"aaa")!==FALSE){ 
    $array[]="aaa"; 
    $s = explode("aaa",$str); 
    $array[]=end($s); 
} 
print_r($array); 

sortie

$ php test.php 
Array 
(
    [0] => aaa 
    [1] => bbb 
) 

En ce qui concerne [1], en fonction de ce qui est à vos critères lorsque « aaa » ne se trouve pas, il peut être aussi simple que de la sous-chaîne de caractère 4 partir à l'aide strpos ().

0

cela correspondra aux groupes mais ce n'est pas très flexible pouvez-vous mettre un peu plus de détails de ce que vous devez faire. Il peut être beaucoup plus facile de saisir trois personnages à la fois et de les évaluer.

J'ai également testé ceci dans une boîte en poudre qui a un goût de regex légèrement différent.

(a {}) * 3,3 (b {}) 3,3

1

Merci pour le brainstorming ici les gars! Je l'ai finalement été en mesure de trouver quelque chose qui fonctionne:

^(?:([^a]*)(aaa))?(.*)$ 
+0

Mais ce n'est pas ce que vous vouliez. Dans votre exemple 1, '\ 1' contiendra' cccbbb'; dans votre exemple 2, '\ 1' contient' ccc', '\ 2' contient' aaa', et '\ 3' contient' bbb'. Que voulez-vous * vraiment * faire? –

+0

Non, dans l'exemple 1 '\ 3 'contiendra' cccbbb', avec ce RegExp. '\ 1' ne peut se produire qu'avec' \ 2', essayez-le. –

+0

Comment cela va-t-il correspondre à 'bbb' pour' cccbbb'? – kennytm

0

comme cela:

$sPattern = "/(aaa?|)(bbb)/"; 

cela fonctionne bien.