9

I need a (php) regex to match Yahoo's username rules:

Use 4 to 32 characters and start with a letter. You may use letters, numbers, underscores, and one dot (.).

Mohammad Naji
  • 5,372
  • 10
  • 54
  • 79

4 Answers4

16
/^[A-Za-z](?=[A-Za-z0-9_.]{3,31}$)[a-zA-Z0-9_]*\.?[a-zA-Z0-9_]*$/

Or a little shorter:

/^[a-z](?=[\w.]{3,31}$)\w*\.?\w*$/i
Markus Jarderot
  • 86,735
  • 21
  • 136
  • 138
  • ok after reading about lookarounds, i get it now, thats pretty sick man, thanks – magicrobotmonkey Oct 06 '08 at 16:51
  • 1
    add `/i` at the end for case insensitive. This way you don't have to specify lower case and upper case letters. – CyberJunkie Jul 23 '11 at 23:17
  • The first one, is it intended to be `/^[A-Za-z](?=[A-Za-z0-9_\.]{3,31}$)[a-zA-Z0-9_]*\.?[a-zA-Z0-9_]*$/` (yours didn't escape the period in the lookahead) I think the unescaped period makes the rest of the [A-Za-z0-9_] pointless. HOWEVER, interestingly I think it still works because it's in the lookahead, meaning the following [a-zA-Z0-9_] also has to be matched, effectively correcting the unescaped `.` But it's also possible I guess to just do this `/^[A-Za-z](?=.{3,31}$)[a-zA-Z0-9_]*\.?[a-zA-Z0-9_]*$/` although I like the original with `\.` best. I'm still new to REGEX, is this correct? – jmk2142 Jun 11 '12 at 05:23
  • Inside `[]` you don't have to escape `.`. It will only match a period. – Markus Jarderot Jun 11 '12 at 08:56
7
/[a-zA-Z][a-zA-Z0-9_]*\.?[a-zA-Z0-9_]*/

And check if strlen($username) >= 4 and <= 32.

Randy
  • 3,972
  • 19
  • 25
  • Now if we could find a way to combine these, just that it MUST match both. – Joel Coehoorn Oct 03 '08 at 21:37
  • Yeah. strlen is a pretty quick operation, though. – Randy Oct 03 '08 at 21:44
  • but i dont have a chance to use strlen, in the spot I'm at, one regex is all I get. – magicrobotmonkey Oct 03 '08 at 21:48
  • What's preventing you from adding a line after the regex? – Randy Oct 03 '08 at 22:05
  • lots of things could. In ASP.Net, for example, you could be using a RegExValidator control. Or he might have a line in a config file he gets to set and that's it. – Joel Coehoorn Oct 04 '08 at 13:30
  • yea its pretty much the latter. I'm trying to keep my class nice and clean. – magicrobotmonkey Oct 05 '08 at 18:20
  • 2
    If you want to keep it to one line in that one location, you can always turn this into a checkusername() function and do the two checks there. Trying to keep classes clean sounds like it's going to leave you with unmaintainable code if you're constantly trying to find ways to combine lines. – Randy Oct 06 '08 at 15:22
2

A one dot limit? That's tricky.

I'm no regex expert, but I think this would get it, except for that:

[A-Za-z][A-Za-z0-9_.]{3,31}

Maybe you could check for the . requirement separately?

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
1

Using lookaheads you could do the following:

^(?=[A-Za-z](?:\w*(?:\.\w*)?$))(\S{4,32})$

Because you didn't specify what type of regex you needed I added a lot of Perl 5 compatible stuff. Like (?: ... ) for non-capturing parens.

Note: I added the missing close paren back in.

Axeman
  • 29,660
  • 2
  • 47
  • 102
  • This one's missing a closing paren, and once i add it (tried a couple places...) I can't get it to match any strings i throw at it. – magicrobotmonkey Oct 06 '08 at 15:40