如何匹配任何大写字母后跟相应的小写字母?

时间:2013-04-24 08:29:10

标签: java regex

我有一个要求,即一个名字不能以3个相同的字母开头而忽略它们的情况。名称以大写字母开头,后跟小写字母。

基本上我可以将整个名称转换为大写,然后匹配像(\p{Lu})\1{3,}.*这样的正则表达式。

但我想知道是否存在符合上述要求的正则表达式,并且不需要对要匹配的字符串进行任何预处理。那么我可以使用什么正则表达式匹配AaDdUu等字符串而不明确指定任何可能的组合?

修改
我接受了Markos的回答。我只需要修复它以使用长度为1和2的名称并将其锚定在开头。因此,我的用例的实际正则表达式为^(\p{Lu})(\p{Ll}?$|(?=\p{Ll}{2})(?i)(?!(\1){2}))

我也赞成了Evgeniy和sp00m的答案,帮助我学习正则表达式的教训。

感谢您的努力。

6 个答案:

答案 0 :(得分:3)

我承认在巨人的肩膀上崛起(这里的其他海报),但这个解决方案实际上适用于你的用例:

final String[] strings = { "Aba", "ABa", "aba", "aBa", "Aaa", "Aab" }; 
final Pattern p = Pattern.compile("(\\p{Lu})(?=\\p{Ll}{2})(?i)(?!(\\1){2})");
for (String s : strings) System.out.println(s + ": " + p.matcher(s).find());

现在我们有:

  1. 前面一个upcase char的匹配;
  2. 以下两个低位字符的先行断言;
  3. 断言这两个字符的另一个前瞻不是和第一个字符相同(忽略大小写)。
  4. 输出:

    Aba: true
    ABa: false
    aba: false
    aBa: false
    Aaa: false
    Aab: true

答案 1 :(得分:2)

    String regex = "(?i)(.)(?=\\p{javaLowerCase})(?<=\\p{javaUpperCase})\\1";
    System.out.println("dD".matches(regex));
    System.out.println("dd".matches(regex));
    System.out.println("DD".matches(regex));
    System.out.println("Dd".matches(regex));

输出

false
false
false
true

答案 2 :(得分:2)

这匹配任何大写字母后跟相同的字母,大写或不大写:

([A-Z])(?i)\1

这匹配任何大写字母后跟相同的字母,但必须小写:

([A-Z])(?!\1)(?i)\1

例如在Java中,

String pattern = "([A-Z])(?!\\1)(?i)\\1";
System.out.println("AA".matches(pattern));
System.out.println("aa".matches(pattern));
System.out.println("aA".matches(pattern));
System.out.println("Aa".matches(pattern));

打印

false
false
false
true

答案 3 :(得分:2)

Evgeniy Dorofeev解决方案正在运行(+1),但它可以更简单,仅使用前瞻

(\\p{Lu})(?=\\p{Ll})(?i)\\1

(\\p{Lu})匹配大写字符并将其存储到\\1

(?=\\p{Ll})positive lookahead assertion,确保下一个字符是小写字母。

(?i)是一个内联修饰符,支持与案例无关的匹配。

\\1匹配第一部分的大写字母(但现在由于前面的修饰符而与案例无关)。

测试它:

String[] TestInput = { "foobar", "Aal", "TTest" };

Pattern p = Pattern.compile("(\\p{Lu})(?=\\p{Ll})(?i)\\1");

for (String t : TestInput) {
    Matcher m = p.matcher(t);
    if (m.find()) {
        System.out.println(t + " ==> " + true);
    } else {
        System.out.println(t + " ==> " + false);
    }
}

输出:

  

foobar ==&gt;假
  Aal ==&gt;真正
  TTest ==&gt;假

答案 4 :(得分:1)

  

我要求说明一个名字不能以3个相同的字母开头而忽略它们的情况。

您应该使用不区分大小写的选项:(?i)

和“全能”\w例如:(?i)(\w)\1{2,}.*

或仅[a-z]例如:(?i)([a-z])\1{2,}.*

答案 5 :(得分:0)

这里可能有必要对不同的要求使用单独的检查,特别是因为需求列表会随着时间的推移而增长。

您描述的要求是:

  

名称不得以3个相同的字母开头,忽略其大小写

  

名称以大写字母开头,后跟小写字母。

对每个进行单独检查(如其他帖子中所述)还允许您向用户提供描述实际错误的正确错误消息。它肯定更具可读性。