正規表現とパターンマッチング

作成日 : 2013-01-26
最終更新日 :

オライリーの JavaScript 第6版 を図書館から借りて、 いろいろ調べている。 10 章の正規表現とパターンマッチングは知らないので、少し調べてみた。

基本的な正規表現

正規表現リテラルを作るのがわかりやすい。このリテラルは、/ と / ではさむ。

const re = /sana/;

この正規表現に対してマッチする文字列はどんなものがあるだろうか。 これを調べるには RegExp.prototype.test を使うのがいい。

re.test("malsana");     // true,   文字列 "sana" にマッチする
re.test("malsanulejo"); // false;  文字列 "sana" にマッチしない

正規表現では、メタ文字を使って多くのパターンを表現できる。たとえば、文字クラスといって、 ある範囲の中の文字の一つにマッチングさせることができる。これには角かっこの組 [] を用いる。

例:アルファベットの母音の組 [AEIOUaeiou]

文字クラスには、範囲を表すハイフン - が使える。これは、文字が一定の順序で並んでいることを前提としている。

例:アルファベット大文字 [A-Z]

例:十進法の数字 [0-9]

例:十六進法の数字 [0-9A-Fa-f]

下のフォームは、正規表現と、その正規表現にマッチさせたい文字列を入れ、[テスト]のボタンをクリックすると、 マッチするかしないかをダイアログウィンドウで表示するプログラムである。このとき、正規表現として ブラウザの JavaScript が受け付けない場合は、「無効な正規表現です」とダイアログウィンドウに表示して終了する。 なお、[ひらがな]から[句読点、記号] のボタンをクリックすると、それぞれの文字種類を表す文字クラスを正規表現のカラムに表示する。

正規表現(//は不要):
オプション グローバル(g) 大文字小文字無視(i) 複数行検索(m) .で改行にマッチ(s) Unicode のコードポイント(u) 粘着質(y)
文字列 :

なお、文字列の置換も参照。

オプションの意味

フォームのオプションの意味について説明する。

グローバル
全体の文字列を見てマッチしたパターンすべてを返す。
大文字小文字無視
このオプションを適用すると、大文字と小文字の区別をしないマッチが行われる。 たとえば、このオプションを適用して正規表現で[a-f] 指定すると [A-F][a-f] が指定されたものと等しい。
複数行検索
複数行検索に対応する。このオプションを適用すると、 複数行ある文字列の行頭にも正規表現 ^文字列 がマッチし、 同様に複数行ある文字列の行末にも正規表現 文字列$ がマッチする。 このオプションがなければ正規表現の ^文字列 は、複数行あっても文字列の冒頭のみにマッチする。 同様にこのオプションがなければ正規表現の 文字列$ は、複数行あっても文字列の末尾のみにマッチする。
.で改行にマッチ
このオプションがなければ任意の1文字を表す正規表現 . は改行文字にはマッチしない。 このオプションを適用すると . に改行文字を含める。
Unicode のコードポイント
このオプションがなければ Unicode 16 ビットのコードユニットごとで文字を区切るが、 このオプションを適用すると Unicode のコードポイントごとで文字を区切る。 コードポイントは通常 16 ビットであるが、 サロゲートペアで表現する一部の漢字は 32 ビットである。 どのような文字でも1単位として厳密に認識するにはコードポイントで文字を区切らなければならない。 たとえば、𩸽(ホッケ)、𩹷(イトウ)などの漢字はサロゲートペアで表現されるため、 このオプションなしの場合は2文字としてマッチすることになるが、 このオプションを適用すると1文字としてマッチする。
粘着質
検索が粘着質 (sticky) であるとは、 文字列内の検索を、正規表現の lastIndex プロパティで示されたインデックスからのみ開始することをいう。 なお、このオプションを適用すると、グローバルオプションは無視される。

JavaScript での正規表現

正規表現クックブック で、JavaScript では適用されていないとされていた項目が、 2021 年 4 月現在どのような状態にあるか、確認してみた。

新たにサポートしたもの

現在でもサポートしていないもの

モード修飾子

(?i)や(?-i)、(?m)のようなモード修飾子は、現在もサポートしていない。これらは「無効な正規表現」とされる。

名前付き後方参照

次のような使い方がある。三好達治の有名な詩「雪」から拝借した。

const snow = '太郎を眠らせ、太郎の屋根に雪ふりつむ';
const regexpTitle = /(?<name>[一-龠]+)を眠らせ、\k<name>/;
const groups = sir.match(regexpTitle).groups;
console.log(groups.name); // 太郎

参考

まりんきょ学問所JavaScript 手習い > 正規表現とパターンマッチング


MARUYAMA Satosi