2010-08-20 2 views
3

J'essaye de concevoir un modèle regex (en PHP) qui permettra n'importe quelle alternance de deux sous-modèles. Donc, si le schéma A correspond à un groupe de trois lettres, et B correspond à un groupe de 2 chiffres, tous ces éléments seraient OK:motif regex pour faire correspondre les sous-modèles alternatifs

 
aaa 
aaa66bbb 
66 
67abc 
12abc34def56ghi78jkl 

Je ne me dérange pas qui commence ou se termine la toujours manipuler séquence, juste après que le premier match, les sous-modèles doivent alterner. Je suis totalement perplexe par ceci - n'importe quels conseils seront reçus avec reconnaissance!

+2

Qu'en est-il de 'abc12def34ghi' et' 56jkl78mno'? Devraient-ils correspondre? –

+0

Ou 'aaa11bbb22', d'ailleurs? – cHao

+0

Oui, absolument. Désolé, je n'étais pas clair.Chaque fois que le motif A ou B correspond, ils peuvent être des chaînes différentes - la seule chose importante est qu'ils doivent alterner. Ainsi 'abc12def34ghi' ou' aaa11bbb22' sont des correspondances valides. –

Répondre

2

Voici une solution générale:

^(?:[a-z]{3}(?![a-z]{3})|[0-9]{2}(?![0-9]{2}))+$ 

Il est un simple alternance - trois lettres ou deux chiffres - mais Les hashs négatifs garantissent que la même alternative ne correspond jamais deux fois de suite. Voici un peu plus élégante solution juste pour PHP:

/^(?:([a-z]{3})(?!(?1))|([0-9]{2})(?!(?2)))+$/ 

Au lieu de taper les mêmes sous-modèles plusieurs fois, vous pouvez les mettre capturer des groupes et utiliser (?1), (?2), etc., pour les appliquer à nouveau chaque fois que ce que vous want-- dans ce cas, dans les lookaheads.

+0

J'aime cette option aussi - similaire à la réponse de cHao, mais peut-être un peu plus élégant? Merci Alan. –

2
"/^(?:$A(?:$B$A)*$B?|$B(?:$A$B)*$A?)\$/" 

correspondra soit le schéma A suivi par cependant beaucoup alternance B et modèle A, et peut-être une finale B ... ou B suivi mais plusieurs paires A-B et d'un A si elle est là.

J'ai fait ceci une chaîne (et ai échappé le $ final) parce que vous allez avoir une certaine interpolation à faire. Assurez-vous que $ A et $ B sont dans une sorte de groupement (comme des parenthèses) si vous voulez que les? '' Correspondent à la bonne chose. Dans vos exemples, $ A pourrait être '([a-zA-Z] {3})' et $ B pourrait être '(\ d \ d)'.

Remarque, si vous voulez faire correspondre un certain nombre de la même lettre ou un chiffre ou dans les cas de même ensemble de lettres ou de chiffres, vous aurez besoin de faire de la magie avec - les références arrières probablement nommées , puisque toute référence arrière numérotée dépendra du nombre de groupes de capture avant celui que vous voulez (ou entre celui que vous voulez et où vous êtes), mais ce nombre se complique si les sous-modèles ont des parenthèses dedans.

+0

([a-zA-Z] {3}) ceci correspondra à 'aXu'. Et (\ d \ d) correspondra à '10' – jigfox

+0

@jigfox: Les motifs correspondent à "un groupe de trois lettres" et "un groupe de deux chiffres", ce qui est exactement ce que le PO a dit. – cHao

+0

Oui, mais les exemples suggèrent un groupe plus spécifique – jigfox

0
/\b(?:(([a-z])\2\2)(?:(([0-9])\4)\1)*(?:([0-9])\5)?|(([0-9])\7)(?:(([a-z])\9\9)\6)*(?:([a-z])\10\10)?)\b/ 

ou si vous souhaitez autoriser tous les ombles non chiffres dans le groupe de trois:

/\b(?:((\D)\2\2)(?:((\d)\4)\1)*(?:(\d)\5)?|((\d)\7)(?:((\D)\9\9)\6)*(?:(\D)\10\10)?)\b/ 

Cela correspond à aucun modèle qui se compose de deux groupes en alternance un groupe est constitué de 3 fois le même omble chevalier et l'autre de 2 fois le même chiffre.

Cette expression rationnelle correspond à

 
aaa 
11 
bbb22 
33ccc 
ddd44ddd 
55eee55 
fff66fff66 
77ggg77ggg 

Mais pas

 
aaa11bbb 
+0

Cela ne permet pas "d'alterner deux sous-motifs". Il ne correspondra qu'aux sous-modèles d'exemple, alors que ce qui était demandé était une solution plus générale. – cHao

+0

Je dirais que c'est une question d'interprétation! – jigfox

+0

Oh, alors c'est "question d'interprétation"! Pendant que vous étiez en train de me déprécier, ce n'était pas si subjectif ... – cHao

Questions connexes