2010-04-23 12 views
2

J'ai du code validant une chaîne de 1 à 32 caractères, qui peut contenir uniquement des caractères alphanumériques et des tirets ('-') mais ne peut pas commencer ou se terminer par un trait d'union.Comment regex correspondre à une chaîne d'alnums et tirets, mais qui ne commence pas ou se termine par un trait d'union?

J'utilise les expressions régulières PCRE & PHP (bien que la partie PHP ne soit pas vraiment importante dans ce cas).

En ce moment, le pseudo-code ressemble à ceci:

if (match("/^[\p{L}0-9][\p{L}0-9-]{0,31}$/u", string) 
    and 
    not match("/-$/", string)) 

    print "success!" 

qui est, je vérifie d'abord que la chaîne est contenu à droite, ne pas être un « - » et est de la bonne longueur, et puis je cours un autre test pour voir que cela ne se termine pas avec un «-».

Des suggestions sur la fusion en une seule expression régulière PCRE?

J'ai essayé d'utiliser des assertions look-ahead/look-behind, mais je n'ai pas réussi à le faire fonctionner.

Répondre

2

Essayez cette expression régulière:

/^[\p{L}0-9](?:[\p{L}0-9-]{0,30}[\p{L}0-9])?$/u 

Et si vous voulez utiliser les assertions de consultation autour de:

/^[\p{L}0-9][\p{L}0-9-]{0,31}$(?<!-)/u 
+0

La première suggestion est belle et semble passer tous mes tests, merci! BTW savez-vous s'il y a une raison de préférer l'un à l'autre? – shevron

+0

@Shahar Evron: Certaines implémentations d'expressions régulières ne prennent pas en charge les assertions look-behind ou les assertions de recherche. Dans ce cas, il est bon de savoir une alternative. – Gumbo

1

Une approche légèrement alternative serait de garder votre classe de personnage dans une seule pièce et être spécifique sur les points où vous ne voulez pas autoriser le trait d'union.

/^(?!-)[\p{L}0-9-]{1,32}(?<!-)$/Du 

Notez également le modificateur D que tout le monde semble toujours oublier. Pour être sûr, vous savez certainement que \pL correspondra beaucoup plus que a-zA-Z, non? Je vérifie juste.

+0

Oui, je suis conscient de cela, c'est pourquoi je l'utilise :) – shevron