2021年12月15日

文字クラス

実践的なタスクを考えてみましょう – "+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\dCSS のあとに数字が続く文字列にマッチします。:

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.BA 、次に改行文字 \n を除く任意の文字、B にマッチします:

alert( "A\nB".match(/A.B/) ); // null (マッチしません)

改行を含めて、ドットを文字通り “任意の文字” としたいケースは多くあります。

これが フラグs がすることです。正規表現がにこのフラグがあると、ドット . は文字通り任意の文字にマッチします。:

alert( "A\nB".match(/A.B/s) ); // A\nB (match!)
Firefox, IE, Edge ではサポートされていません

最新のサポート状況については 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-51 - 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 が必要です。

チュートリアルマップ