1 つの大きな正規表現を記述する代わりに、個別の正規表現を記述して、必要な各条件をテストする方が明確です。
ユーザー名に文字、数字、 から までの ASCII 記号、およびスペースのみが含まれているかどうかをテスト!し@ます^(\p{L}|\p{N}|[!-@]| )+$。ユーザー名が有効であるためには、これが一致する必要があります。\p{L}Unicode 文字のクラスと Unicode 番号のクラスの使用に注意してください\p{N}。
ユーザー名に連続したスペースが含まれているかどうかをテストします: \s\s+. これが一致する場合、ユーザー名は無効です。
シンボルが連続して発生するかどうかをテストします: [!-@][!-@]+. これが一致する場合、ユーザー名は無効です。
これは、書かれているとおりに基準を満たしています。
ただし、ユーザー名の書き方によっては、「Éponine」のような完全に有効な名前でも、このアプローチでは拒否される場合があります。これは、"É" が、U+00C9 LATIN CAPITAL E WITH ACUTE (これは と一致する\p{L}) またはEU+02CA MODIFIER LETTER ACUTE ACCENT (と一致しない\p{L}) のようなものとして記述できるためです。
Regular-Expressions.info はそれをよりよく言います:
繰り返しますが、「文字」は実際には「Unicode コード ポイント」を意味します。\p{L} は、カテゴリ「文字」の単一のコード ポイントに一致します。入力文字列が U+0061 U+0300 としてエンコードされている場合、アクセントのない a に一致します。入力が U+00E0 としてエンコードされている場合、アクセントと一致します。その理由は、コード ポイント U+0061 (a) と U+00E0 (à) の両方がカテゴリ「文字」にあるのに対し、U+0300 はカテゴリ「マーク」にあるためです。
Unicode は毛むくじゃらであり、ユーザー名の文字を制限することは必ずしも良い考えではありません。これを実行してもよろしいですか?