-6

I want to validate a text that need have more than 3 [aA-zZ] chars, not need continous.

/^(?![_\-\s0-9])(?!.*?[_\-\s]$)(?=.*[aA-zZ]{3,})[_\-\sa-zA-Z0-9]+$/.test("aaa123") => return true; /^(?![_\-\s0-9])(?!.*?[_\-\s]$)(?=.*[aA-zZ]{3,})[_\-\sa-zA-Z0-9]+$/.test("a1b2c3") => return false;

Can anybody help me?

楊詠仁
  • 3
  • 1

3 Answers3

0

You need to group .* and [a-zA-Z] in order to allow optional arbitrary characters between English letters:

^(?![_\-\s0-9])(?!.*?[_\-\s]$)(?=(?:.*[a-zA-Z]){3,})[_\-\sa-zA-Z0-9]+$
                                 ^^^         ^
                                    Add this

Demo:

var re = /^(?![_\-\s0-9])(?!.*?[_\-\s]$)(?=(?:.*[aA-zZ]){3,})[_\-\sa-zA-Z0-9]+$/;
console.log(re.test("aaa123"));
console.log(re.test("a1b2c3"));

By the way, [aA-zZ] is not a correct range definition. Use [a-zA-Z] instead. See here for more details.

Dmitry Egorov
  • 9,542
  • 3
  • 22
  • 40
0

How about replacing and counting?

var hasFourPlusChars = function(str) {
    return str.replace(/[^a-zA-Z]+/g, '').length > 3;
};

console.log(hasFourPlusChars('testing1234'));
console.log(hasFourPlusChars('a1b2c3d4e5'));
arbuthnott
  • 3,819
  • 2
  • 8
  • 21
  • Execution time is longer. – le_top Sep 30 '17 at 11:45
  • I actually suspect the fastest execution is a for-loop and a counter! But for one-time, user-initiated code I don't stress *too* much over minor speed differences. – arbuthnott Sep 30 '17 at 12:16
  • I agree that performance depends on the nubmer of times you need to execute the code. ** I added this method to the speed test and it is the slowest (half the speed of the fastest implementation so far). – le_top Sep 30 '17 at 12:32
0

Correction of the regex

Your repeat condition should include the ".*". I did not check if your regex is correct for what you want to achieve, but this correction works for the following strings:

$testStrings=["aaa123","a1b2c3","a1b23d"];
foreach($testStrings as $s)
   var_dump(preg_match('/^(?![_\-\s0-9])(?!.*?[_\-\s]$)(?=.*[a-zA-Z]){3,}[_\-\sa-zA-Z0-9]+$/', $s));

Other implementations

As the language seems to be JavaScript, here is an optimised implementation for what you want to achieve:

"a24be4Z".match(/[a-zA-Z]/g).length>=3

We get the list of all matches and check if there are at least 3. That is not the "fastest" way as the result needs to be created. )

/(?:.*?[a-zA-Z]){3}/.test("a24be4Z")

is faster. ".*?" avoids that the "test" method matches all characters up to the end of the string before testing other combinations.

As expected, the first suggestion (counting the number of matches) is the slowest. Check https://jsperf.com/check-if-there-are-3-ascii-characters .

le_top
  • 445
  • 3
  • 12