正規表現を使用する Java の行にたどり着きました。姓のユーザー入力が必要です
return lastName.matches( "[a-zA-z]+([ '-][a-zA-Z]+)*" );
[ '-] の機能を教えてください。また、「+」と「*」の両方が同時に必要で、[ '-][a-zA-Z] が括弧で囲まれているのはなぜですか?
あなたの RE は:[a-zA-z]+([ '-][a-zA-Z]+)*
私はそれをその構成要素に分解します:
[a-zA-Z]+
文字列は任意の文字で始まるか、a-zまたはA-Zを 1 回以上繰り返す必要があります ( +)。
([ '-][a-zA-Z]+)*
[ '-]<space>、'、またはの任意の 1 文字-。
[a-zA-Z]+ここでも、任意の文字a-zまたはA-Zが 1 回以上繰り返されます。
この文字 ('-とa-ZA-Z) の組み合わせは、0 回以上繰り返すことができます。
なぜ[ '-]ですか?などのハイフネーションされた名前、 のようなHiggs-Bosonアポストロフィを含む名前O'Reilly、または のようなスペースを含む名前を許可しますVan Dyke。
これは、ダブルバレル (スペースまたはハイフン) または I-don't-know-what-to-call-it のような名前に一致するパターンのようO'Gradyです ... 例:
似合うだろう
counter-terrorism
De'ville
O'Grady
smith-jones
smith and wesson
しかし、それは一致しません
jones-
O'Learys'
#hashtag
Bob & Sons
アイデアは、最初[A-Za-z]+の文字が可能な限りすべての文字を消費した後、次の文字がスペース、アポストロフィ、またはハイフン ( [ '-]) でない限り、一致はそこで終了するというものです。これらの文字の 1 つが存在する場合は、その後に少なくとも 1 つの文字が続く必要があります。
多くの人がこれに苦労しています。[A-Za-z]+[ '-]?[A-Za-z]*セパレーターと文字の余分なチャンクの両方がオプションであると考えて、単純に のようなものを書きます。しかし、それらは独立してオプションではありません。区切り記号 ( [ '-])がある場合は、その後に少なくとも 1 文字を追加する必要があります。それ以外の場合は、文字列R'- j'-'を有効なものとして扱います。あなたの正規表現にはその問題はありません。
ところで、正規表現にタイプミスがあります: [a-zA-z]. すべての大文字と小文字に一致するため[A-z]、入力が有効である限り正しく機能しているように見えるため、注意が必要です。しかし、コードポイントがたまたま と の間にあるいくつかの非文字にも一致しZますa。そして、そのエラーをキャッチする IDE や正規表現ツールはほとんどありません。