1

Requirements:

The regex should match a string that does not contain the "@" symbol, but contains at least two alpha characters, and is between 2 and 50 characters long total.

Pass examples:

"Hi there!%%#"
"         fd"
"  9 z 80212132 z"

Fail examples:

"anything with @"
"a"
"  9 z 80212132 "
"This string does not contain at symbol and has two characters but is too long!"

I believe I am close, however this will fail with any characters other than [a-zA-Z] and I'm not sure why:

^((?![@])(?=[a-zA-Z]).){2,50}$

2 Answers 2

2

Your regex does not check for at least two alphas.

You can use the following regex:

^(?=(?:[^A-Za-z]*[A-Za-z]){2})[^@]{2,50}$

See the regex demo

Explanation:

  • ^ - start of string
  • (?=(?:[^A-Za-z]*[A-Za-z]){2}) - there must be at least two occurrences of zero or more non-alpha characters followed with one alpha
  • [^@]{2,50} - 2 to 50 characters other than @
  • $ - end of string.

var re = /^(?=(?:[^A-Za-z]*[A-Za-z]){2})[^@]{2,50}$/; 
var strs = ['Hi there!%%#', '         fd' , '  9 z 80212132 z', 'anything with @ a', '  9 z 80212132 ', 'This string does not contain at symbol and has two characters but is too long!'];
 // demo
for (var s of strs) {
  document.body.innerHTML += "<i>" + s.replace(/ /g, '&nbsp;') + "</i> test result: <b>" +  re.test(s) + "</b><br/>";
}

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

5 Comments

Note that the regex in the regex demo is a bit different as it is a multiline demo, the real regex demo is in the snippet I added to the answer.
Thank you! I see you added the newline character in your example to prove the point. I need to add a few more characters to that set anyway. The only thing I took out is the "?:" as the preceding "?=" is also not matching. Thank you again!
If you replace a non-capturing group with a capturing one ("took out the ?:) you lose on performance (just a tiny bit). But it is your choice: readability or clean match object/performance.
I see now. I thought positive lookahead was non-matching by default, but that doesn't make sense. Thanks!
Yes, lookaheads/lookbehinds do not consume characters (these are not part of the match value, and the index is kept at the point where the regex engine entered the lookaround), non- and capturing groups do. See more here.
0

It makes sure:

  • no char is @
  • 2 alpha chars at least
  • total between 2 & 50

^(?!.*@)(?=(?:.*[a-zA-Z]){2}).{2,50}$

DEMO

2 Comments

This will not allow newlines in the input string and one of the conditions is expressed as an additional lookahead which means additional overhead for the engine (a negated character class is more efficient). 151 steps (this regex) vs. 61 steps (mine) (I admit there is a difference between PHP and JS regex engines, but they do share similar performance issues).
That's what I thought when I saw your well made regex ;-) ... Then on a second thought, I realised that 1st condition will make the parser quit if unverified, so it wont bother checking the rest... Try testing it when @ at 50th position ;-) 7steps vs 100steps for yours xD ... Anyway, I'll leave it as slightly different version =)

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.