2010-06-04 13 views
4

Je suis assez nouveau pour les expressions régulières et de plus en plus je les utilise, plus je les aime. Je travaille sur une expression régulière qui doit remplir les conditions suivantes:Expression régulière Positive Lookahead sous-chaîne

  1. doit commencer par un caractère Alpha
  2. Sur les trois caractères suivants, au moins un doit être un caractère Alpha.
  3. Tout ce qui suit les quatre premiers caractères est une correspondance automatique.

J'ai actuellement l'expression rationnelle suivante: ^[a-zA-Z](?=.*[a-zA-Z]).{1}.*$

La question que je me présente en est que mon positif (?=.*[a-zA-Z]).{1} est préanalyse pas contraint aux trois caractères qui suivent le caractère alpha. J'ai l'impression de manquer un concept ici. Qu'est-ce qui me manque dans cette expression?

Merci à tous.

+0

Sur 2: un seul et exactement un, ou au moins un? – polygenelubricants

+0

désolé à ce sujet. Au moins un doit être un caractère alpha. – user90279

Répondre

3

Le .* dans votre lookahead fait ça. Vous devriez limiter la portée ici comme

^[a-zA-Z](?=.{0,2}[a-zA-Z]).{1}.*$ 

Modifier: Si vous voulez vous assurer, qu'il ya au moins 4 caractères de la chaîne, vous pouvez utiliser une autre préanalyse comme ceci:

^[a-zA-Z](?=.{3})(?=.{0,2}[a-zA-Z]).{1}.*$ 
+0

Cela correspondra également 'aa' –

+0

@Jan: L'OP ne mentionne pas qu'il veut au moins quatre caractères, mais j'ai mis à jour ma réponse pour donner cette option. – Jens

+0

En quoi '. {1}' est-il différent de '.'? ;-) (Pour l'anecdote, votre seconde expression est plus facile à écrire sous la forme '^ [a-zA-Z] (? =. {0,2} [a-zA-Z]). {3}. *'. + 1 de moi, approche élégante. – Tomalak

1

Vous devrez probablement faire une solution de contournement. Quelque chose comme:

^[a-z](?=([a-z]..|.[a-z].|..[a-z])).{3}.* 
  • premier char [az]
  • positive préanalyse, que ce soit d'abord, ou deuxième ou troisième caractère est az ([a-z]..|.[a-z].|..[a-z])
  • Autres trucs
3

Que voulez-vous lookahead? Pourquoi ne pas simplement utiliser

^[a-zA-Z](..[a-zA-Z]|.[a-zA-Z].|[a-zA-Z]..) 

et être heureux?

+0

Bon point. Utiliser lookahead et (surtout) lookbehind quand ce n'est pas nécessaire peut nuire aux performances. +1 pour la simplification – Robusto

+0

Solution parfaitement raisonnable. Je suppose que je pensais aux choses. Juste pour le plaisir, et si je disais qu'au moins un des 30 prochains caractères doit être alpha. Existe-t-il un moyen d'encapsuler cette idée dans une déclaration plus simple? – user90279

+0

@Robusto: Pas dans ce cas, du moins pas au-delà des différences «académiques». – Tomalak

0

Changer le * dans votre Lookahead ? pour obtenir m/^[a-zA-Z](?=.?[a-zA-Z]).{1}.*$

Si je comprends vos critères qu'il fixe à cause du changement de greediness.

Ces correspondent bien:

a2a3-match 
2aaa-no match 
Aaaa-match 
a333-no match 
+0

Va également correspondre 'aa' –