次の要件を満たす正規表現を作成するのに助けが必要です。
- 手紙から始める
- 文字または数字で終わる
- 内部文字として、文字、数字、アンダースコア、およびハイフンのみを使用してください
次の式は、アンダースコアを最後の文字として許可することを除いて、適切に機能します。最後の文字には文字または数字のみを許可する必要があります。
^[A-Za-z][\w-]*\w$
これにはPOSIX 文字クラスを使用できます。特に、 の短縮形である英数字クラスを使用できます[A-Za-z0-9]
。例えば:
^[A-Za-z][\w-]*[[:alnum:]]$
あなたが求めていることを行う方法の1つは、負の先読み制約を使用することです:
^[A-Za-z][\w-]*(?!_)\w$
もう 1 つの方法は、必要な文字クラスを書き出すことです (Tcl では、クラスとアンダースコアが と定義\w
されています)。[[:alnum:]_]
alnum
^[A-Za-z][\w-]*[[:alnum:]]$
これらは、まったく同じ文字列を受け入れます。どちらが良いですか?確かに唯一確実な方法は、テストすることです (これらのタイミングは、古い Tcl バージョンの古いラップトップでのものです。絶対的なタイミングではなく、相対的なタイミングを見てください)。
% set a "abc123abc123abc123_123"
abc123abc123abc123_123
% set b "abc123abc123abc123123_"
abc123abc123abc123123_
% regexp {^[A-Za-z][\w-]*(?!_)\w$} $a
1
% regexp {^[A-Za-z][\w-]*(?!_)\w$} $b
0
% time {regexp {^[A-Za-z][\w-]*(?!_)\w$} $a} 1000
21.207069999999998 microseconds per iteration
% time {regexp {^[A-Za-z][\w-]*(?!_)\w$} $b} 1000
20.577612000000002 microseconds per iteration
% regexp {^[A-Za-z][\w-]*[[:alnum:]]$} $a
1
% regexp {^[A-Za-z][\w-]*[[:alnum:]]$} $b
0
% time {regexp {^[A-Za-z][\w-]*[[:alnum:]]$} $a} 1000
4.0455700000000006 microseconds per iteration
% time {regexp {^[A-Za-z][\w-]*[[:alnum:]]$} $b} 1000
3.510597 microseconds per iteration
本当に必要なクラスを記述できる場合は、先読み制約を使用しないでください。(REエンジンにも将来最適化の可能性がありそうです...)
^[a-zA-Z][-\w]*[a-zA-Z\d]$
またはを使用する必要があります^[a-zA-Z][-\w]*[^\W_]$
^[a-z][a-z0-9_\-]+[a-z0-9]$(?i)