7

I have a requirement that says a name must not start with 3 identical letters ignoring their case. A name starts with an upper case letter followed by lower case letters.

Basically I could convert the whole name to upper case and then match with a regex like (\p{Lu})\1{3,}.*.

But I was wondering if there exists a regex that matches the above requirements and does not need any preprocessing of the string to be matched. So what regex can I use to match strings like Aa, Dd or Uu without explicitly specifiying any possible combination?

EDIT:
I accepted Markos answer. I just needed to fix it to work with names of length 1 and two and anchor it at the beginning. So the actual regex for my use case is ^(\p{Lu})(\p{Ll}?$|(?=\p{Ll}{2})(?i)(?!(\1){2})).

I also upvoted the answers of Evgeniy and sp00m for helping me to learn a lesson in regexes.

Thanks for your efforts.

4

6 に答える 6

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 == > false
Aal ==> true
TTest ==> false

于 2013-04-24T09:01:08.140 に答える
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

This matches any uppercased letter followed by the same letter, uppercased or not:

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

This matches any uppercased letter followed by the same letter, but necessarily lowercased:

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

For example in 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));

Prints

false
false
false
true
于 2013-04-24T08:55:32.927 に答える
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 に答える