使用正则表达式匹配非连续的大写字母和小写字母

3
std::string s("AAA");
std::smatch m;
std::regex e("(?=.{3,}[A-Z])(?=.{0,}[a-z]).*");
output = std::regex_search(s, m, e);

这里应该有3个或更多大写字母和零个或多个小写字母。然而输出为0,意味着失败了。当我尝试将0替换为1并使用s("AAA4")时,它可以正常工作。

所以现在我想让它允许零个或多个,但好像它不接受零。我甚至尝试了等价于{0,}的量词符“*”,仍然无法工作。

这里是一个例子:

string1 "AAA"
string2 "AAAb"
string3 "AbAA"

以下正则表达式适用于字符串1和字符串2,因为大写字母是连续的:
[A-Z]{3,}[a-z]*

以下正则表达式适用于string2和string3,但当没有小写字母时,即使我指定为0,它也无法工作。
(?=.{3,}[A-Z])(?=.{0,}[a-z]).*

我需要的是一个正则表达式,可以处理以下所有情况:
  • 允许0个或多个小写字母出现
  • 验证字符串中是否有3个大写字母,但它们不必像字符串3那样连续出现

你是否正在寻找 std::regex e("(?:[^A-Z]*[A-Z]){3}"); 来检查一个包含3个大写ASCII字母的字符串? - Wiktor Stribiżew
你是什么意思?出现次数是多少?请在问题中只添加相关细节。当你说可以有0个或更多小写字母时,听起来好像你并不在乎字符串中是否有任何小写字母。 - Wiktor Stribiżew
在这个正则表达式中,我将3作为大写字母的变量发送,0作为小写字母的变量发送,因此除了当输入0时,它能很好地工作。请问怎样做才能使其正常运行? - MHxy
3
为什么要使用正则表达式?为什么不只需在字符串上迭代一次并计算大写字母的数量? - OrangeDog
这是一种方法,但实际上我正在使用函数输入来构建正则表达式,然后显示形成的正则表达式以供将来使用和修改。 - MHxy
显示剩余3条评论
2个回答

1
这里应该有3个或更多大写字母和零个或多个小写字母。
您的(?=.{3,}[A-Z])(?=.{0,}[a-z]).*正则表达式匹配了一行中的一部分,由0+个字符组成(.*),以任意3个或更多个字符开头,后跟一个大写ASCII字母((?=.{3,}[A-Z])),并且至少有一个小写ASCII字母((?=.{0,}[a-z]))。
要匹配一个包含x个大写ASCII字母和y个小写ASCII字母的字符串,您需要使用
std::regex e("^(?=(?:[^A-Z]*[A-Z]){x}[^A-Z]*$)(?=(?:[^a-z]*[a-z]){y}[^a-z]*$)");
                                   ^                              ^

请参见正则表达式演示细节:
  • ^ - 字符串的开头
  • (?=(?:[^A-Z]*[A-Z]){x}[^A-Z]*$) - 正向先行断言 1,在字符串开头触发,检查是否有 x 个序列:
    • [^A-Z]* - 零个或多个非大写 ASCII 字母的字符
    • [A-Z] - 大写 ASCII 字母
    • [^A-Z]*$ - 零个或多个非大写 ASCII 字母的字符,直到字符串结尾 ($)
  • (?=(?:[^a-z]*[a-z]){y}[^a-z]*$) - 正向先行断言 2,也在字符串开头触发 (因为先行断言是零宽断言),检查是否有 y 个序列:
    • [^a-z]* - 零个或多个非小写 ASCII 字母的字符
    • [a-z] - 小写 ASCII 字母
    • [^a-z]*$ - 零个或多个非小写 ASCII 字母的字符,直到字符串结尾。

这很有效,解释也非常好,谢谢。问题只是缺少一些东西。我使用的是像 {3,} 这样的 x 和 y 范围,并尝试将其用于您的正则表达式,但它不适用于此。例如,对于大写字母的 {3,5} 范围,输入超过五个字符被接受了,这是错误的。 - MHxy
好的,明白了,你需要在模式中添加一点内容。 - Wiktor Stribiżew
感谢您的帮助。 - MHxy

-1
^(?=.*[a-z])(?=.{3,}[A-Z]).+$

解释:

^                  // the start of the string
(?=.*[a-z])        // use positive look ahead to see if at least one lower case letter exists
(?=.{3,}[A-Z])     // use positive look ahead to see if at least 3 upper case letter exists
.+                 // gobble up the entire string
$  

当字符串为'AAA'时,这个不起作用,因为(?=.*[a-z])必须至少有一个小写字母。 - MHxy
(?=.{3,}[A-Z])是不正确的,它的解释也是错误的。它检查是否存在一个大写字母在任意3个或更多字符之后。 - Wiktor Stribiżew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接