2013-04-15 3 views
1

J'ai cet exemple RegEx: http://regexr.com?34hihsvnComment optimiser cette regex en chaîne (1234-12345-1)

Je me demande s'il y a une façon plus élégante de l'écrire, ou peut-être plus optimisé façon?

Voici les règles:

  • Digits et tirets seulement.
  • Ne doit pas contenir plus de 10 chiffres.
  • Doit avoir deux traits d'union.
  • Doit comporter au moins un chiffre entre chaque tiret.
  • Le dernier numéro ne doit être qu'un chiffre.

Je suis nouveau à ce que j'apprécierais tous les conseils ou astuces.

Si le lien expire, le texte à rechercher est

---------- 
22-22-1 
22-22-22 
333-333-1 
333-4444-1 
4444-4444-1 
4444-55555-1 
55555-4444-1 
666666-7777777-1 
88888888-88888888-1 
1-1-1 
88888888-88888888-22 
22-333- 
333-22 
---------- 

Mon expression rationnelle est \b((\d{1,4}-\d{1,5})|(\d{1,5}-\d{1,4}))-\d{1}\b

J'utilise ce site pour les tests: http://gskinner.com/RegExr/

Merci pour toute aide, Nick

Répondre

1

Voici un regex je suis venu avec:

(?=\b[\d-]{3,10}-\d\b)\b\d+-\d+-\d\b 

Il utilise une anticipation pour valider les informations avant de tenter le match. Donc, il recherche entre 3-10 caractères dans la classe de [\d-] suivi par un dash et un digit. Et puis après cela, vous avez la correspondance réelle pour confirmer que le format de votre chaîne est en réalité digit(dash)digit(dash)digit.

A partir de vos chaînes d'échantillons de cette expression régulière:

22-22-1 
333-333-1 
333-4444-1 
4444-4444-1 
4444-55555-1 
55555-4444-1 
1-1-1 

Il correspond également les chaînes suivantes:

22-7777777-1 
1-88888888-1 
+0

Cela correspond également à la fois 22-7777777-1 et 1-88888888-1 qui est également une exigence que j'ai manqué. –

+0

Basé sur votre description J'espérais que c'était une exigence. Je suis content de voir que j'avais raison. Je vais mettre à jour ma réponse avec ça. Espérons que cela a aidé. –

1

Votre expression rationnelle autorise uniquement un premier et un second groupe de chiffres d'une longueur maximale de 5. Par conséquent, les chaînes valides telles que 1-12345678-1 ou 123456-1-1 ne seront pas appariées.

Cela fonctionne regexp pour les exigences données:

\b(?:\d\-\d{1,8}|\d{2}\-\d{1,7}|\d{3}\-\d{1,6}|\d{4}\-\d{1,5}|\d{5}\-\d{1,4}|\d{6}\-\d{1,3}|\d{7}\-\d{1,2}|\d{8}\-\d)\-\d\b 

(RegExr)

+0

Bon point! J'ai oublié que j'avais besoin de faire correspondre 22-7777777-1 ou 1-88888888-1. –

1

Vous pouvez l'utiliser avec le modificateur m(changer le mode multiligne sur):

^\d(?!.{12})\d*-\d+-\d$ 

ou celui-ci sans le modificateur m:

\b\d(?!.{12})\d*-\d+-\d\b 

par la conception de ces deux modèles correspondent à au moins trois chiffres séparés par des traits d'union (donc pas besoin de mettre un endroit quantificateurs {5,n}, il est inutile). Les modèles sont aussi construire plus rapidement à l'échec:

  • Je l'ai choisi de les commencer par un chiffre \d, ainsi chaque début d'une ligne ou d'un mot-limite pas suivie d'un chiffre est immédiatement mis au rebut. Autre chose, en utilisant un seul chiffre, je connais la longueur de la chaîne restante.
  • Ensuite, je teste la limite supérieure de la longueur de la chaîne avec un test négatif s'il y a un caractère de plus que la longueur maximale (s'il y a 12 caractères à cette position, il y a 13 caractères au moins dans la chaîne). Pas besoin d'utiliser plus descriptif que le méta-caractère point ici, le but est de tester rapidement la longueur.
  • Enfin, je décris la fin de la chaîne sans faire quelque chose de particulier. C'est probablement la partie la plus lente de la tendance, mais cela n'a pas d'importance étant donné que l'écrasante majorité des postes inutiles ont déjà été écartés.
+0

ok, donc cela fonctionne aussi ... Qu'est-ce que le mode multi-ligne? Comment fonctionne ce Regex? À votre santé. –

+0

Ok, j'ai ajouter une explication –