(C++) 确定不匹配的正则表达式捕获组

(C++) Determine the unmatched regex capture groups

本文关键字:正则表达式 不匹配 C++      更新时间:2023-10-16

我想检查密码是否满足以下要求:

它应该:

  • 至少包含 1 个小写字母 (ASCII 97-122)
  • 至少包含 1 个字母 (65-90)
  • 至少包含 1 位数字
  • 至少包含 1 个特殊字符(33-47、58-64、91-96、123-126)
  • 长度在 8 到 20 个字符之间

它还应该告诉我哪些要求不符合。


给定以下表达式,我可以使用库中std::regexregex_match()对其进行验证

regex re("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!-/:-@[-`{-~])(\S){8,20}$");

但是这样我只能知道它是否匹配,因为它返回了一个boolean

鉴于此,在向表达式添加一些捕获组后,我尝试像下面这样迭代match_results

std::string str("AAAaaa111$$$");
std::regex rx("^((?=.*[a-z]).*)((?=.*[A-Z]).*)((?=.*[0-9]).*)((?=.*[!-/:-@[-`{-~]).*)(\S){8,20}$");
std::match_results< std::string::const_iterator > mr;
std::regex_search(str, mr, rx);
std::cout << "size: " << mr.size() << 'n'; // 6 or 0 only ?
for (int i = 0; i < mr.size(); i++) {
std::cout << "index: " << i << "t --> t" << mr.str(i) << endl;
}
if (regex_match(str, rx)) {
cout << "tests passed" << endl;
}
else {
cout << "tests failed" << endl;
}

它产生了以下输出:

size: 6
index: 0         -->    AAAaaa111$$$
index: 1         -->    AA
index: 2         -->    Aa
index: 3         -->
index: 4         -->
index: 5         -->    $
tests passed
Press any key to continue . . .

我想实现的是分辨出哪些组不匹配。例如,对于输入:SamplePassword1只有第 4 组不匹配,因为它不包含特殊字符。然后,可以通知用户密码不符合哪些特定要求。因此,SamplePassword1$将在每组中进行匹配并通过。

是否可以使用单个正则表达式而不是为每个要求使用单独的正则表达式来完成此任务?


我在这里遇到了一个类似的问题,但它在 C# .NET 中并使用命名捕获组。

var re = new Regex("((?<a>a)|(?<b>b))");
var ma = re.Match("a");
Console.WriteLine("a in a: " + ma.Groups["a"].Success); //true
Console.WriteLine("b in a: " + ma.Groups["b"].Success); //false
std::regex rx("^((?=.*[a-z]))?((?=.*[A-Z]))?((?=.*[0-9]))?((?=.*[!-/:-@[-`{-~]))?(\S){8,20}$");

并与mr[i].first == str.end()核实。演示

也就是说,回想一下这句话:

有些人在遇到问题时会想"我知道,我会使用正则表达式"。现在他们有两个问题。