views:

163

answers:

4

I would like to test if user type only alphanumeric value or one "-".

hello-world                 -> Match
hello-first-world           -> match
this-is-my-super-world      -> match
hello--world                -> NO MATCH
hello-world-------this-is   -> NO MATCH
-hello-world                -> NO MATCH (leading dash)
hello-world-                -> NO MATCH (trailing dash)

Here is what I have so far, but I dont know how to implement the "-" sign to test it if it is only once without repeating.

var regExp = /^[A-Za-z0-9-]+$/;
+5  A: 

Here you go (this works).

var regExp = /^[A-Za-z0-9]+([-]{1}[A-Za-z0-9]+)+$/;

letters and numbers greedy, single dash, repeat this combination, end with letters and numbers.

Brad
+2  A: 

(^-)|-{2,}|[^a-zA-Z-]|(-$) looks for invalid characters, so zero matches to that pattern would satisfy your requirement.

MikeWyatt
+10  A: 

Try this:

/^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$/

This will only match sequences of one or more sequences of alphanumeric characters separated by a single -. If you do not want to allow single words (e.g. just hello), replace the * multiplier with + to allow only one or more repetitions of the last group.

Gumbo
Perfect, clearly but briefly explained, and not over-complex. Live example: http://jsbin.com/iceho3/2
T.J. Crowder
+1, very nice .
M42
Just for my knowledge: what does the `?:` mean?
Nivas
@Nivas: It's not a capture group. (Normally parens are capture groups.) http://www.visibone.com/regular-expressions/ By putting the optional additional bit in a group, Gumbo can then use `*` to indicate zero or more of the sequences in that group.
T.J. Crowder
sorry guys, i have probably didnt say it clearly, but the single "-" should not be there. It could be there, it should not at all.
praethorian
@Nivas: `(?:…)` is a so called non-capturing group. It’s similar to the normal group `(…)` but you can’t reference the sequence that is matched by its content.
Gumbo
**(?:regex)** Non-capturing parentheses group the regex so you can apply regex operators, but do not capture anything and do not create backreferences. ref: http://www.regular-expressions.info/refadv.html
Brad
@praethorian: In that case replace the `*` multiplier by `?`. That means the group is optional.
Gumbo
@praethorian: What do you mean? Gumbo's expression doesn't allow just a `-`. (It also disallows leading and trailing `-`s.): http://jsbin.com/iceho3/3
T.J. Crowder
@paethorian and @Gumbo, the `*` also makes it optional. what he probably wants is to replace the `*` with `+`
ormuriauga
@Crowder, @Gumbo, @Brad: Thanks! I think I understand, will go over the links...
Nivas
A: 

I'm not entirely sure if this works because I haven't done regex in awhile, but it sounds like you need the following:

/^[A-Za-z0-9]+(-[A-Za-z0-9]+)+$/

You're requirement is split up in the following:

  • One or more alphanumeric characters to start (that way you ALWAYS have an alphanumeric starting.
  • The second half entails a "-" followed by one or more alphanumeric characters (but this is optional, so the entire thing is required 0 or more times). That way you'll have 0 or more instances of the dash followed by 1+ alphanumeric.

I'm just not sure if I did the regex properly to follow that format.

myermian
Close, but `\w` allows `_`. (Some other edits: Use a non-capturing group rather than capturing, no need for `[]` around `\w`, and need the `$` at the end; result: `/^\w+(?:-\w+)*$/`). But again, the OP didn't want `_`.
T.J. Crowder
putting `\w` inside brackets is not neccessary, otherwise it looks fine, although if you start it with `^` you probably meant to end it with `$`. Also he probably wants the last `*` to be a `+` although his examples are not clear on the subject.
ormuriauga
`[A-z]` matches all uppercase and lowercase ASCII letters, plus `[`, `]`, `_`, `^`, backslash, and backtick. To match just the letters, you have to use use `[A-Za-z]`.
Alan Moore
I'm good at knowing HOW a regex should act, but the little things about it always get me... I guess that's why I explained how to break it up in groups.
myermian