ECMAScript assertions: how to specify the maximum number of matches of a certain character class?

Hi,

I want to modify the following regular expression:


1
2
 // string: "Ab,CDf"
 // reg expr: "(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}" 


which represents:


// logical AND via lookahead: this password matches IF it contains
    // at least one lowercase letter
    // AND at least one uppercase letter
    // AND at least one punctuation character
    // AND be at least 6 characters long




Want to place a restriction that there may be no more than 3 lower case characters.

I tried the following with no success (I have been trying for several hours now):


 
// reg expr: "(?=(.*[[:lower:]]){2,3})(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}" 



Any suggestions? I am trying to specify what I want using reg expression assertions but maybe I am not an expert on them right now. A small push might clear me up.


Thanks,
Juan
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <regex>
#include <iostream>
#include <iomanip>
#include <string>

int main()
{
    std::regex const pw_verify 
    {
        R"__((?=.*[[:punct:]]))__"     // at least one punctuation mark
        R"__((?=.*[[:upper:]]))__"     // at least one uppercase letter
        R"__((?=.*[[:lower:]]))__"     // at least one lowercase letter
        R"__((?!.*?[[:lower:]]{4}))__" // not at least four lowercase letters
        R"__(.{6,})__"                 // at least six characters
    };
    
    for (std::string line; std::getline(std::cin, line);)
        if (std::regex_match(line, pw_verify)) 
            std::cout << std::quoted(line) << ": valid password\n";
        else
            std::cout << std::quoted(line) << ": bad password\n";
}
Great mbozzi. Just one question: why is there a ? after the * in this line:

 
R"__((?!.*?[[:lower:]]{4}))__"



why not just
 
R"__((?!.*[[:lower:]]{4}))__"


?

Thanks
Actually, the greedy match (no question mark) is a better choice in this case.

However, there needs to be a non-capturing group around .*[[:lower:]] so that the pattern will match lowercase letters that aren't next to each other.

R"__((?!(?:.*[[:lower:]]){4}))__"

So that !aaAAAAaa is rejected, for example.
Topic archived. No new replies allowed.