実践的なタスクを考えてみましょう – "+7(903)-123-45-67"
という電話番号があり、その文字列のすべての数字を見つける必要があります: 79035419441
。
そのためには、数値以外を見つけて除去します。文字クラス(Character class)はこのとき役立ちます。
文字クラス は集合から任意の表現にマッチする特別な表記法です。
最初に “数字” クラスから見ていきましょう。\d
と書きます。それを正規表現のパターンに入れ検索すると、任意の数字にマッチします。
例えば、正規表現 /\d/
は1つの数字を探します:
let str = "+7(903)-123-45-67";
let reg = /\d/;
alert( str.match(reg) ); // 7
上の例では g
フラグがないので、正規表現は最初のマッチだけを探します。
すべての数字を探すために g
フラグを追加しましょう:
let str = "+7(903)-123-45-67";
let reg = /\d/g;
alert( str.match(reg) ); // マッチした配列: 7,9,0,3,1,2,3,4,5,6,7
// 結果から数字だけの電話番号を作りましょう:
alert( str.match(regexp).join('') ); // 79035419441
先程は数字のための文字クラスでした。同様に他の文字クラスがあります。
最も使われるのは以下のものです:
\d
(“d” は “digit” より)- 数字:
0
から9
の文字です。 \s
(“s” は “space” より)- スペース記号: スペース、タブ
\t
、改行\n
といくつかのあまり使われない文字が含まれます:\v
,\f
や\r
です。 \w
(“w” は “word” より)- “言葉” の文字: 英語アルファベットの文字または数字またはアンダースコア
_
。 非英語の文字(キリル文字やヒンディー語など)は\w
に属しません。
例えば、\d\s\w
は "1 Z"
のように、数字のあとに空白文字、単語文字が続く文字列を意味します。
正規表現は通常の記号と文字クラス両方を含む場合があります。
例として、CSS\d
は CSS
のあとに数字が続く文字列にマッチします。:
let str = "CSS4 is cool";
let reg = /CSS\d/
alert( str.match(reg) ); // CSS4
また、多くの文字クラスを使うこともできます:
alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // 'HTML5'
マッチ(各文字クラスは結果文字に対応します):
逆のクラス
すべての文字クラスには “逆のクラス” があります。それは同じ文字ですが大文字で表されます。
“逆” は、他のすべての文字にマッチすることを意味します。例えば:
\D
- 非数字:
\d
以外の任意の字です。例えば文字です。 \S
- 非スペース:
\s
以外のすべての文字です。例えば文字です。 \W
- 非単語文字:
\w
以外の文字。
チャプターの先頭では、電話番号 +7(903)-123-45-67
からすべての数字を取得する方法を見ました。文字列から “純粋な” 電話番号を取得してみましょう。:
let str = "+7(903)-123-45-67";
alert( str.match(/\d/g).join('') ); // 79031234567
代わりの方法は、文字列から非数字を見つけ削除することです:
let str = "+7(903)-123-45-67";
alert( str.replace(/\D/g, "") ); // 79031234567
ドットは任意の文字です
ドット .
は 改行を除く任意の文字 にマッチする特別な文字クラスです。
例:
alert( "Z".match(/./) ); // Z
また正規表現の中にある場合:
let reg = /CS.4/;
alert( "CSS4".match(reg) ); // CSS4
alert( "CS-4".match(reg) ); // CS-4
alert( "CS 4".match(reg) ); // CS 4 (空白も文字です)
ドットは “任意の文字” を意味しますが、 “文字の欠如” ではないことに注意してください。それにマッチする文字が必要です::
alert( "CS4".match(/CS.4/) ); // null, ドットに対する文字がないのでマッチしません
Dot as literally any character with “s” flag
デフォルトでは、ドットは改行文字 \n
にはマッチしません。
例えば、正規表現 A.B
は A
、次に改行文字 \n
を除く任意の文字、B
にマッチします:
alert( "A\nB".match(/A.B/) ); // null (マッチしません)
改行を含めて、ドットを文字通り “任意の文字” としたいケースは多くあります。
これが フラグs
がすることです。正規表現がにこのフラグがあると、ドット .
は文字通り任意の文字にマッチします。:
alert( "A\nB".match(/A.B/s) ); // A\nB (match!)
最新のサポート状況については https://caniuse.com/#search=dotall を確認してください。執筆時点では Firefox, IE, Edge は含まれていません。
幸いなことに、どこでも機能する代替手段があります。 “任意の文字” にマッチさせたい場合、[\s\S]
という正規表現を使用します。
alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!)
パターン [\s\S]
は文字通りです: “スペース文字 or スペースではない文字”。つまり、“なんでも” です。[\d\D]
のような別のクラスのペアを使うこともできます。
このトリックはどこでも機能します。また、パターンに通常の “改行なし” のドットも必要な場合に、 s
フラグを設定したくない場合にも使用できます。
通常、スペースにはほどんど注意を払いません。私達にとって、文字列 1-5
と 1 - 5
はほとんど同じです。
ですが、スペースを考慮していない正規表現の場合、うまく動作しないことがあります。
ハイフンで区切られた数字を見つけましょう:
alert( "1 - 5".match(/\d-\d/) ); // null, no match!
正規表現 \d - \d
にスペースを追加して修正しましょう。:
alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, これで動作します
// or we can use \s class:
alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, これもOKです
スペースは文字です。他の文字と同様に重要です。
正規表現にスペースを追加したり削除して同じ動作を期待することはできません。
つまり、正規表現ではすべての文字が重要であり、スペースもそうです。
サマリ
文字クラスを説明しました:
\d
– 数字\D
– 非数字\s
– スペース記号、タブ、改行\S
–\s
以外\w
– 英語文字、数字、アンダースコア'_'
\W
–\w
以外.
– 改行以外の任意の文字。's'
フラグがあれば任意文字です。
ですが、これで全部ではありません。
JavaScript が文字列に使用する Unicode エンコーディングは、文字の多くのプロパティを提供します。
これらのプロパティで検索することもできます。それには、次の記事で説明するフラグ pattern:u
が必要です。
コメント
<code>
タグを使ってください。複数行の場合は<pre>
を、10行を超える場合にはサンドボックスを使ってください(plnkr, JSBin, codepen…)。