実践的なタスクを考えてみましょう – "+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…)。