2

正規表現を使用して、次の単語に一致させたい

  • 手紙で始まる
  • 英語のアルファベットがあります
  • 数字、ピリオド(.)、ハイフン(-)、アンダースコア(_)
  • ピリオド、ハイフン、アンダースコアを 2 つ以上連続して使用しないでください
  • 複数のピリオドまたはハイフンまたはアンダースコアを使用できます

例えば、

flin..stones または flin__stones または flin--stones

許可されていません。

fl_i_stones または fli_st.ones または flin.stones または flinstones

許可されています 。

これまでのところ、私の正規表現は^[a-zA-Z][a-zA-Z\d._-]+$ です

だから私の質問は、正規表現を使用してそれを行う方法です

4

1 に答える 1

5

これを解決するには、先読み後方参照を使用できます。ただし、現時点では少なくとも 2 文字が必要であることに注意してください。開始文字と別の文字 ( による+)。おそらく、2 番目の文字クラスを 0 回以上繰り返すことができるようにする必要があります+*

^(?!.*(.)\1)[a-zA-Z][a-zA-Z\d._-]*$

先読みはどのように機能しますか? まず、否定的な先読みです。内部のパターンが一致する場合、先読みによってパターン全体が失敗し、その逆も同様です。したがって、 2 つの連続する文字がある場合に一致するパターンを内部に持つことができます。まず、文字列 ( ) 内の任意の位置を探し.*、次に単一の (任意の) 文字 ( .)を一致させ、括弧でキャプチャします。したがって、その 1 文字はキャプチャ グループに入り1ます。そして、このキャプチャ グループの後にそれ自体が続く必要があります (それを で参照します\1)。したがって、内側のパターンは文字列内のすべての位置で試行されます (バックトラッキングのため)) それ自体が後に続く文字があるかどうか。これらの 2 つの連続した文字が見つかった場合、パターンは失敗します。それらが見つからない場合、エンジンは先読みが開始された場所 (文字列の先頭) に戻り、実際のパターンの照合を続行します。

または、これを 2 つの個別のチェックに分割することもできます。有効な文字と開始文字の 1 つ:

^[a-zA-Z][a-zA-Z\d._-]*$

そして、連続した文字の 1 つ (一致結果を反転できる場所):

(.)\1

これにより、コードの可読性が大幅に向上し (先読みよりもわかりにくいため)、パターン内の実際の問題を検出して、適切で役立つエラー メッセージを返すこともできます。

于 2013-01-04T23:43:44.737 に答える