2020年2月29日

数量詞 +, *, ?, および {n}

例えば、+7(903)-123-45-67のような文字列があり、その中のすべての数字を見つけたいとします。しかし、以前とは異なり、1桁の数字ではなく、7, 903, 123, 45, 67のような完全な数字に関心があります。

数字は、1つ以上の数字 \d の並びです。必要な数をマークするために、*量指定子*を追加できます。

量 {n}

最も単純な量指定子は、中括弧内の数字です: {n}

量指定子は、文字(または文字クラス、または[...]集合など)に追加され、必要な数を指定します。

いくつかの高度な形式があります、例を見てみましょう

正確な数: {5}

\d{5} は正確に 5 桁の数字を表し、\d\d\d\d\dと同じです。

以下の例は、5桁の数字を探します

alert( "I'm 12345 years old".match(/\d{5}/) ); //  "12345"

長い数字を除外するために\bを追加できます: \b\d{5}\b

範囲: {3,5}、3~5回一致

3~5桁の数字を見つけるために、中括弧に制限を入れることができます: \d{3,5}

alert( "I'm not 12, but 1234 years old".match(/\d{3,5}/) ); // "1234"

上限を省略できます。

すると、正規表現 \d{3,} は、長さが3以上の数字の並びを探します

alert( "I'm not 12, but 345678 years old".match(/\d{3,}/) ); // "345678"

文字列 +7(903)-123-45-67 に戻りましょう。

数字は、1つ以上の連続した数字の並びです。そのため、正規表現は\d{1,}です

let str = "+7(903)-123-45-67";

let numbers = str.match(/\d{1,}/g);

alert(numbers); // 7,903,123,45,67

ショートハンド

最もよく使用される量指定子のためのショートハンドがあります

+

「1つ以上」を意味し、{1,}と同じです。

たとえば、\d+は数字を探します

let str = "+7(903)-123-45-67";

alert( str.match(/\d+/g) ); // 7,903,123,45,67
?

「ゼロまたは1つ」を意味し、{0,1}と同じです。言い換えれば、記号をオプションにします。

たとえば、パターン ou?r は、oの後にゼロまたは1つのu、そしてrが続くものを探します。

そのため、colou?rcolorcolour の両方を見つけます

let str = "Should I write color or colour?";

alert( str.match(/colou?r/g) ); // color, colour
*

「ゼロ以上」を意味し、{0,}と同じです。つまり、文字は任意の回数繰り返されるか、存在しない可能性があります。

たとえば、\d0* は数字の後に任意の数のゼロが続くもの(多くてもなくてもよい)を探します

alert( "100 10 1".match(/\d0*/g) ); // 100, 10, 1

これを+(1つ以上)と比較してください

alert( "100 10 1".match(/\d0+/g) ); // 100, 10
// 1 not matched, as 0+ requires at least one zero

その他の例

量指定子は非常に頻繁に使用されます。それらは複雑な正規表現の主要な「構成要素」として機能するので、さらに例を見てみましょう。

10進数の分数(浮動小数点付きの数字)の正規表現: \d+\.\d+

実行

alert( "0 1 12.345 7890".match(/\d+\.\d+/g) ); // 12.345

<span><p> のような「属性のない開始 HTML タグ」の正規表現。

  1. 最もシンプルなもの: /<[a-z]+>/i

    alert( "<body> ... </body>".match(/<[a-z]+>/gi) ); // <body>

    この正規表現は、文字 '<' の後に 1 つ以上のラテン文字が続き、次に '>' が続くものを探します。

  2. 改善: /<[a-z][a-z0-9]*>/i

    標準によれば、HTML タグ名は <h1> のように、最初の位置を除く任意の位置に数字を持つことができます。

    alert( "<h1>Hi!</h1>".match(/<[a-z][a-z0-9]*>/gi) ); // <h1>

正規表現「属性のない開始または終了 HTML タグ」: /<\/?[a-z][a-z0-9]*>/i

パターンの先頭付近にオプションのスラッシュ /? を追加しました。バックスラッシュでエスケープする必要がありました。そうしないと、JavaScriptはそれがパターンの終わりだと考えてしまいます。

alert( "<h1>Hi!</h1>".match(/<\/?[a-z][a-z0-9]*>/gi) ); // <h1>, </h1>
正規表現をより正確にするためには、多くの場合、より複雑にする必要があります

これらの例で1つの共通ルールが見られます。正規表現がより正確であるほど、長くて複雑になります。

たとえば、HTMLタグの場合、より単純な正規表現: <\w+>を使用できます。しかし、HTMLにはタグ名に対するより厳格な制限があるため、<[a-z][a-z0-9]*>の方が信頼性が高くなります。

<\w+> を使用できますか、それとも <[a-z][a-z0-9]*> が必要ですか?

実際には、どちらのバリエーションも許容されます。それは、「余分な」一致にどれだけ寛容になれるか、そして、他の手段によって結果からそれらを削除することが難しいかどうかによって異なります。

タスク

重要度: 5

省略記号、つまり3つ(またはそれ以上?)のドットが連続して並んでいるものを見つける正規表現を作成してください。

確認

let regexp = /your regexp/g;
alert( "Hello!... How goes?.....".match(regexp) ); // ..., .....

解決策

let regexp = /\.{3,}/g;
alert( "Hello!... How goes?.....".match(regexp) ); // ..., .....

ドットは特殊文字であるため、エスケープして\.として挿入する必要があることに注意してください。

#ABCDEFのように記述されたHTMLカラーを検索する正規表現を作成します。最初に#があり、次に6つの16進数文字が続きます。

使用例

let regexp = /...your regexp.../

let str = "color:#121212; background-color:#AA00ef bad-colors:f#fddee #fd2 #12345678";

alert( str.match(regexp) )  // #121212,#AA00ef

追伸 このタスクでは、#123rgb(1,2,3)などの他のカラー形式は必要ありません。

6つの16進数文字が続く#を探す必要があります。

16進数文字は、[0-9a-fA-F]として記述できます。または、iフラグを使用する場合は、[0-9a-f]だけです。

次に、量指定子{6}を使用して、それらの6つを探すことができます。

結果として、正規表現は次のようになります: /#[a-f0-9]{6}/gi

let regexp = /#[a-f0-9]{6}/gi;

let str = "color:#121212; background-color:#AA00ef bad-colors:f#fddee #fd2"

alert( str.match(regexp) );  // #121212,#AA00ef

問題は、長いシーケンスの中で色を見つけてしまうことです

alert( "#12345678".match( /#[a-f0-9]{6}/gi ) ) // #123456

それを修正するために、最後に\bを追加できます

// color
alert( "#123456".match( /#[a-f0-9]{6}\b/gi ) ); // #123456

// not a color
alert( "#12345678".match( /#[a-f0-9]{6}\b/gi ) ); // null
チュートリアルマップ