tags:

views:

399

answers:

12

I am trying to validate user id's matching the example:

smith.jack or smith.jack.s

In other words, any number of non-whitespace characters (except dot), followed by exactly one dot, followed by any number of non-whitespace characters (except dot), optionally followed by exactly one dot followed by any number of non-whitespace characters (except dot). I have come up with several variations that work fine except for allowing consecutive dots! For example, the following Regex

^([\S][^.]*[.]{1}[\S][^.]*|[\S][^.]*[.]{1}[\S][^.]*[.]{1}[\S][^.]*)$

matches "smith.jack" and "smith.jack.s" but also matches "smith..jack" "smith..jack.s" ! My gosh, it even likes a dot as a first character. It seems like it would be so simple to code, but it isn't. I am using .NET, btw.

Frustrating.

+1  A: 
[^\s.]+\.[^\s.]+(\.[^\s.]+)?

BTW what you asked for allows "." and ".."

BCS
are you sniffing my keyboard? You missed a ?, btw
Vinko Vrsalovic
I'm assuming that "a.b." is invalid thus the missing ? is not needed
BCS
Yes, realized so by garrett's comment
Vinko Vrsalovic
+6  A: 

that helps?

/^[^\s\.]+(?:\.[^\s\.]+)*$/

or, in extended format, with comments (ruby-style)

/
  ^           # start of line
  [^\s\.]+    # one or more non-space non-dot
  (?:         # non-capturing group
    \.        # dot something
    [^\s\.]+  # one or more non-space non-dot
  )*          # zero or more times
  $           # end of line
/x

you're not clear on how many times you can have dot-something, but you can replace the * with {1,3} or something, to specify how many repetitions are allowed.

i should probably make it clear that the slashes are the literal regex delimiter in ruby (and perl and js, etc).

kch
Your regex didn't work; Guvante's did -- and may the bird of paradise fly up your nose, too. What kind of "more description title" would you have preferred? Something like "Regex to validate any non-zero number of non-whitespace non-dot characters, followed by a dot, etc"? Please enlighten me.
Yes, that would be a good title. Or "Regex to validate name pattern". Something at least a little less generic.
lordscarlet
A: 

I think you'd benefit from using + which means "1 or more", instead of * meaning "any number including zero".

Lot105
+2  A: 

You are using the * duplication, which allows for 0 iterations of the given component.

You should be using plus, and putting the final .[^.]+ into a group followed by ? to represent the possibility of an extra set.

Might not have the perfect syntax, but something similar to the following should work.

^[^.\s]+[.][^.\s]+([.][^.\s]+)?$

Or in simple terms, any non-zero number of non-whitespace non-dot characters, followed by a dot, followed by any non-zero number of non-whitespace non-dot characters, optionally followed by a dot, followed by any non-zero number of non-whitespace non-dot characters.

Guvante
Works great! Thanks! Now to try to parse it using wetware to see how to understand and learn from it.
This one seems to fail when the third group is more than one character, e.g. jack.smith.blah
Terhorst
In my application it is happy with jack.smith.blah
This is because the author changed it after I made my comment.http://stackoverflow.com/revisions/87953/list
Terhorst
A: 
(^.)+|(([^.]+)[.]([^.]+))+

But this would match x.y.z.a.b.c and from your description, I am not sure if this is sufficiently restrictive.

BTW: feel free to modify if I made a silly mistake (I haven't used .NET, but have done plently of regexs)

Ryan Delucchi
A: 
[^.\s]+\.[^.\s]+(\.([^\s.]+?)?

has unmatched paren. If corrected to

[^.\s]+\.[^.\s]+(\.([^\s.]+?))?

is still too liberal. Matches a.b. as well as a.b.c.d. and .a.b
If corrected to

[^.\s]+\.[^.\s]+(\.([^\s.]+?)?)

doesn't match a.b

A: 
^([^.\W]+)\.?([^.\W]+)\.?([^.\W]+)$

This should capture as described, group the parts of the id and stop duplicate periods

workmad3
Doesn't match a.b
+1  A: 

^([^.\s]+)\.([^.\s]+)(?:\.([^.\s]+))?$

Terhorst
Longer than Guvante's earlier answer above, but still works fine!
As a bonus, it captures groups well, too.
Terhorst
+2  A: 

I'm not familiar with .NET's regexes. This will do what you want in Perl.

/^\w+\.\w+(?:\.\w+)?$/

If .NET doesn't support the non-capturing (?:xxx) syntax, use this instead:

/^\w+\.\w+(\.\w+)?$/

Note: I'm assuming that when you say "non-whitespace, non-dot" you really mean "word characters."

Michael Carman
This doesn't match, for example: descartes.rené
Terhorst
What \w matches depends on your locale setting. It does in Perl, anyway, and should do so in .NET as well.
Michael Carman
A: 

I took a slightly different approach. I figured you really just wanted a string of non-space characters followed by only one dot, but that dot is optional (for the last entry). Then you wanted this repeated.

^([^\s\.]+\.?)+$

Right now, this means you have to have at least one string of characters, e.g. 'smith' to match. You, of course could limit it to only allow one to three repetitions with

^([^\s\.]+\.?){1,3}$

I hope that helps.

Trey
+2  A: 

I realise this has already been solved, but I find Regexpal extremely helpful for prototyping regex's. The site has a load of simple explanations of the basics and lets you see what matches as you adjust the expression.

Jon Cage
A: 

RegexBuddy Is a good (non-free) tool for regex stuff

BCS