0

I am creating a Regular Expression in JavaScript which should look for both numbers (at least 1) and letters (at least 1), with the total length being between 6 and 10. I came across some unexpected behavior.

My regex - /^[a-z+\d+]{6,10}$/g.

This doesn't work properly because being in a character class, it checks for letters or numbers, but noth BOTH. Therefore, I would expect "123456" to fail, because while it contains 6 characters, and has at least 1 digit, it does not include 1 letter.

However, in the below code snippet, when I store the regex in the rgx variable and use .test() on it, it somehow correctly returns false, as shown in the second console.log statement. But on the very next line when I directly use the regex with .test(), it returns true.

let rgx = /^[a-z+\d+]{6,10}$/g;

// works fine
console.log(rgx.test("abcd12"));

// returns false
console.log(rgx.test("123456"));

// same regex returns true
console.log(/^[a-z+\d+]{6,10}$/g.test("123456"));

What's going on here?

4
  • 1
    Unrelated, but + in you character class means “allow the + character”, not “one or more of the preceding”. Commented Nov 5, 2017 at 9:56
  • 1
    Try to execute the test() function twice with the same regex object and the same testing string: It won't return the same boolean. And here is why: siderite.blogspot.com/2011/11/… Commented Nov 5, 2017 at 10:00
  • Have you tried reducing it to more simple parts? For example, what happens with a regex of just ^/[\d]$/g, and rgx.test("1")`? Commented Nov 5, 2017 at 10:00
  • developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Nov 5, 2017 at 10:05

2 Answers 2

4

Try

let rgx = /^[a-z+\d+]{6,10}$/g;
let rgx2 = /^[a-z+\d+]{6,10}$/g;
console.log(rgx.test("abcd12")); //true
console.log(rgx2.test("123456")); //true

It's because

Javascript RegExp object is stateful i.e. if you re-use a RegExp object (with 'g' flag set), subsequent matches would start from the end of the last match.

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

Comments

-1

try this instead /^[^a-z0-9]{6,10}$/g

2 Comments

let regex = /^[a-z0-9]{6,10}$/g; let regex2 = /^[a-z0-9]{6,10}$/g; console.log(regex.test("abcd09")); //true console.log(regex2.test("123456")); //true
The regex of the OP was not the problem, but rather the reuse of the regex for 2 test operations.

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.