7

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

基本上我可以将整个名称转换为大写,然后与(\p{Lu})\1{3,}.*.

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

编辑:
我接受了马科斯的回答。我只需要修复它以使用长度为 1 和 2 的名称并在开头锚定它。所以我的用例的实际正则表达式是^(\p{Lu})(\p{Ll}?$|(?=\p{Ll}{2})(?i)(?!(\1){2})).

我还赞成 Evgeniy 和 sp00m 的答案,因为它们帮助我学习了正则表达式。

感谢您的努力。

4

6 回答 6

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. 匹配前面的一个大写字符;
  2. 以下两个小写字符的前瞻断言;
  3. 另一个断言这两个字符与第一个字符不同(忽略大小写)的前瞻。

输出:

阿坝:真的
阿巴:假
aba: 假的
aBa: 假的
啊:假的
阿布:是的
于 2013-04-24T09:35:16.743 回答
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
于 2013-04-24T08:46:41.673 回答
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
于 2013-04-24T08:55:32.927 回答
2

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

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

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

(?=\\p{Ll})是一个肯定的前瞻断言,确保下一个字符是小写字母。

(?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);
    }
}

输出:

foob​​ar ==>假
Aal ==> 真
TTest ==> 假

于 2013-04-24T09:01:08.140 回答
1

我有一个要求,即名称不能以 3 个相同的字母开头,忽略大小写。

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

和“包罗万象”,\w例如:(?i)(\w)\1{2,}.*

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

于 2013-04-24T09:07:31.787 回答
0

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

您的要求是:

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

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

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

于 2013-04-24T09:39:37.803 回答