2019年12月10日

量指定子 +, *, ? と {n}

+7(903)-123-45-67 という文字列があり、すべての文字を見つけたいとします。しかし、以前とは違い、数字だけでなく完全な数字が欲しいです: 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.

from-to のでカウント: {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
?

“0 か 1” を意味し、{0,1} と同じです。つまりシンボルをオプションにします。

例えば、パターン ou?ro に続く 0 または 1つの u、そして続けて r です。

なので、単語 color では or を見つけ、colour では our を見つけます。:

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

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

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

下の例は、ゼロが任意の数続く数字を探します:

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

'+' (1つ以上) と比較すると:

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

より多くの例

量指定子はとてもよく使われます。これらは複雑な正規表現を実現するためのメインの “ビルディングブロック” のなので、より多くの例を見ていきましょう。

"少数" (浮動小数点を持つ数値)の正規表現: \d+\.\d+
実演:
alert( "0 1 12.345 7890".match(/\d+\.\d+/g) ); // 12.345

"属性なしの HTML の開始タグ" の正規表現 (<span><p> など)

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

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

    文字 '<' に続けて1つ以上の英語文字、その後 '>'

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

    標準では、HTMLタグ名は1文字目以外の任意の場所で数字が使えます。例: <h1>

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

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

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

```js run
alert( "<h1>Hi!</h1>".match(/<\/?[a-z][a-z0-9]*>/gi) ); // <h1>, </h1>
```
より精密、はより複雑、を意味します

これらの例から1つの共通するルールが見えてきます: 正規表現がより詳細/精密になるほど、パターンはより長く複雑になります。

例えば、HTMLタグはより簡単な正規表現が使えます: <\w+>.

なぜなら、\w は任意の英語文字または数字または '_' を意味するためです。また正規表現は例えば <_> のような非タグにもマッチします。しかし <[a-z][a-z0-9]*> よりもずっと簡単です。

私たちは <\w+> で良いですか?それとも <[a-z][a-z0-9]*> が必要ですか?

実際にはどちらもパターンも許容されます。“余分な” マッチや他の手段でフィルタするのが難しいかどうかという点に対してどれだけ寛容であるかによります。

タスク

重要性: 5

省略記号(連続した3つ(以上?)のドット)を見つける正規表現を作成してください。

これでチェックします:

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

解答:

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

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

#ABCDEF と書かれた HTML カラーを探す正規表現を作成してください。: 最初に #、次に 6 つの16進数文字です。

使用例:

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

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

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

P.S. このタスクでは #123rgb(1,2,3) のような別のフォーマットを考える必要はありません。

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

16進数文字は [0-9a-fA-F] で表現できます。もしくは i フラグを使うと、[0-9a-f] とすることができます。

次に、量指定子 {6} を使い6文字を探すことができます。

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

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

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

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

この問題は、より長い一連の色を見つけることです:

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

修正するには、末尾に \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
チュートリアルマップ

コメント

コメントをする前に読んでください…
  • 自由に記事への追加や質問を投稿をしたり、それらに回答してください。
  • 数語のコードを挿入するには、<code> タグを使ってください。複数行の場合は <pre> を、10行を超える場合にはサンドボックスを使ってください(plnkr, JSBin, codepen…)。
  • 記事の中で理解できないことがあれば、詳しく説明してください。