正規表現を使用する 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 や正規表現ツールはほとんどありません。