1
^[a-zA-Z0-9]*[a-zA-Z0-9 _][a-zA-Z0-9]{2,24}$

That's what I have right now.

I want to require an alphanumeric first; allow for alphanumerics, underscores, hyphens, periods, and spaces; require that it end with an alphanumeric. But I only want to allow as many as 3 of those special characters.

I'm primarily confused about how to limit the number of the special characters.

3
  • 1
    give some example valid and invalid data Commented Feb 1, 2013 at 15:05
  • If you're allowing as many as 3 special characters, do they have to be in a row, or 3 total? So is something like A-B-A valid? Commented Feb 1, 2013 at 15:19
  • 3 total. They can be consecutive or spread out. They just can't start or end the string. Commented Feb 1, 2013 at 15:21

3 Answers 3

3

You can also use this regex:

/^(?!(?:[a-z\d]*[_. -]){4})[a-z\d][\w. -]{0,22}[a-z\d]$/i

The look-ahead (?!(?:[a-z\d]*[_. -]){4}) is to check that there are less than 4 appearances of invalid characters. If there are 4 or more, then the pattern inside the negative look-ahead would match, and make the look-ahead fail.

Since the string must start and end with alphanumeric, and the length is at least 2, it is possible to specify [a-z\d] as start and end of the string. The rest of the character in between can contain any of [a-zA-Z0-9_. -] repeated 0 to 22 times, since 2 characters are already use for the starting ending alphanumeric.

Sign up to request clarification or add additional context in comments.

4 Comments

Hmm, I've never seen a look-ahead inside a negative look-ahead. That's pretty slick. What's the difference between ?: and ?= ?
So close. As far as I can tell the only problem with your solution is that HTML5's regex checker is case-sensitive and does not respond to the /i flag. So it's necessary to drop it and manually specify uppercase letters as valid. This means that the pattern should be ^(?!(?:[a-zA-Z\d]*[_. -]){4})[a-zA-Z\d][\w. -]{2,22}[a-zA-Z\d]$ Thanks, nhahtdh.
@iamnotmaynard: That's not look-ahead inside negative look-ahead. It's just simply a negative look-ahead (?!pattern), with a non-capturing group (?:pattern) repeating 4 times.
For some reason I wasn't familiar with that. Thanks for teaching me something.
1

Okay, this should be the last edit: Didn't think about the total character limit. Added look-ahead (assuming your flavor of regex supports it).

There may be a better way than this, but it's not coming to me (maybe using lookaheads). Here's what I can think of:

^(?=^.{2,24}$)[a-zA-Z0-9]+([a-zA-Z0-9]*[_\-. ]){0,3}[a-zA-Z0-9]+$

It's not too pretty but it should work.

2 Comments

Can be simplified to ^[a-zA-Z0-9]+(([a-zA-Z0-9]*[_\-. ]){0,3}[a-zA-Z0-9]+)?$, and the length check can be done separately.
True, if needed (or preferred for style or just to keep the regex from getting to messy).
0
^[a-zA-Z0-9]+[ _.-]?[a-zA-Z0-9]*[ _.-]?[a-zA-Z0-9]*[ _.-]?[a-zA-Z0-9]+$

There's probably a better way to do this, but I think you could just have the invalid characters be optional, appearing at most three times, with the other valid characters showing up 0 or more times in between them

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.