web-dev-qa-db-fra.com

Expression régulière - commençant et finissant par une lettre, acceptant uniquement les lettres, les chiffres et _

J'essaie d'écrire une expression régulière qui spécifie que le texte doit commencer par une lettre, chaque caractère doit être une lettre, un chiffre ou un trait de soulignement. Pour le moment, je n'ai que ^[a-zA-Z]\w[a-zA-Z1-9_], mais cela ne semble pas fonctionner correctement car il ne correspond jamais qu'à 3 caractères et autorise des traits de soulignement répétés. Je ne sais pas non plus comment spécifier les exigences pour le dernier caractère.

16
jreid9001
^[A-Za-z][A-Za-z0-9]*(?:_[A-Za-z0-9]+)*$
9
Alan Moore

Je vais tenter le coup:

/^[a-z](?:_?[a-z0-9]+)*$/i

A expliqué:

/
 ^           # match beginning of string
 [a-z]       # match a letter for the first char
 (?:         # start non-capture group
   _?          # match 0 or 1 '_'
   [a-z0-9]+   # match a letter or number, 1 or more times
 )*          # end non-capture group, match whole group 0 or more times
 $           # match end of string
/i           # case insensitive flag

Le groupe sans capture prend en charge a) l’interdiction de deux _ (il oblige au moins une lettre ou un chiffre par groupe) et b) l’autorisation que le dernier caractère soit une lettre ou un chiffre.

Quelques chaînes de test:

"a": match
"_": fail
"zz": match
"a0": match
"A_": fail
"a0_b": match
"a__b": fail
"a_1_c": match
41
gnarf

Voici une solution utilisant un lookahead négatif (non supporté par tous les moteurs de regex):

^[a-zA-Z](((?!__)[a-zA-Z0-9_])*[a-zA-Z0-9])?$

Vérifiez que cela fonctionne comme prévu:

import re
tests = [
   ('a', True),
   ('_', False),
   ('zz', True),
   ('a0', True),
   ('A_', False),
   ('a0_b', True),
   ('a__b', False),
   ('a_1_c', True),
]

regex = '^[a-zA-Z](((?!__)[a-zA-Z0-9_])*[a-zA-Z0-9])?$'
for test in tests:
   is_match = re.match(regex, test[0]) is not None
   if is_match != test[1]:
       print "fail: "  + test[0]
4
Mark Byers

voyant comment les règles sont assez compliquées, je suggérerais ce qui suit:

/^[a-z](\w*)[a-z0-9]$/i

faire correspondre la chaîne entière et capturer des caractères intermédiaires. Ensuite, soit avec les fonctions de chaîne ou l'expression régulière suivante:

/__/

vérifie si la partie capturée a deux traits de soulignement à la suite. Par exemple, en Python, cela ressemblerait à ceci:

>>> import re
>>> def valid(s):
    match = re.match(r'^[a-z](\w*)[a-z0-9]$', s, re.I)
    if match is not None:
        return match.group(1).count('__') == 0
    return False
0
SilentGhost