はじめに
正規表現を使用していると、パターン内の条件をまとめて扱いたい場面がでてくることがあります。
そのようなときにはキャプチャグループを利用すると簡潔に記述できるようになります。
また、キャプチャグループにマッチした文字列をパターンの後方で参照することもできます。
この記事ではキャプチャグループを利用した条件の書き方などについて見ていきたいと思います。
キャプチャグループ
グループ化は(と)で囲むことで行えます。
グループ化をすると、そのグループに対して{n,m}や.、*などの量指定子を使用することもできます。
const regex = /(abc){3}/
"abc".match(regex) // null
"abcabc".match(regex) // null
"abcabcabc".match(regex) // ["abcabcabc", "abc"]
"abcabcabcabc".match(regex) // ["abcabcabc", "abc"]
上の例では"abc"を3回繰り返している文字列にマッチするようになっています。
matchがマッチ箇所の他に"abc"を返していますが、これはマッチした箇所に関するキャプチャグループです。
キャプチャグループを返り値に含めたくない場合には、(?:と)で囲んでグループ化を行います。
const regex = /(?:abc){3}/
"abcabcabc".match(regex) // ["abcabcabc"]
キャプチャグループの参照
()によってグループ化すると、グループ内のパターン(サブパターン)にマッチする文字列を後方で参照できるようになります。
例えば、'または"で囲まれた文字のパターンを記述したいときには、['"][^'"]*['"]のように書いてしまうと'abc"や"def'のようにクオテーションの種類が異なる文字列にもマッチしてしまいます。
2つ目の['"]には、1つ目の['"]で合致した符号と同じものが入ってほしいわけですが、そこでグループ化とその参照を利用できます。
キャプチャグループの参照は\1や\2のように、パターン内で何番目のグループを参照したいかを指定できます1。
const regex = /(['"])[^'"]*\1/
"\'abc\"".match(regex) // null
"\"abc\"".match(regex) // [""abc"", """]
"'abc'".match(regex) // ["'abc'", "'"]
(['"])はパターンの中で1番目にあるグループなので、\1で参照できます。
"'abc'"は'から始まっているため、1番目のグループでは'が条件に合致します。
\1によって、パターン'を参照できるようになります。
マッチしたサブパターンを定数のように扱えるわけですね。
名前付きキャプチャグループ
キャプチャグループには名前をつけることができ、その名前を使用して\1や\2の代わりに参照を行うこともできます。
名前をつけてグループ化するには、(?<group_name>と)で囲みます。
参照する際には、\1などの代わりに\k<quote>のように\k<group_name>の形で指定できます。
const regex = /(?<quote>'|")[^'"]*\k<quote>/
"'abc\"".match(regex) // null
"\"abc\"".match(regex) // [""abc"", """]
"'abc'".match(regex) // ["'abc'", "'"]
|: 選択
|を使用すると、左の条件、「または」、右の条件にマッチすることを表現できます。
先のクオテーションの例では文字クラスを使用していましたが、|を使って書き換えることもできます。
const regex = /('|")[^'"]*\1/
"\'abc\"".match(regex) // null
"\"abc\"".match(regex) // [""abc"", """]
"'abc'".match(regex) // ["'abc'", "'"]
|は左から順に比較が行われていくため、複数の条件に合致するケースがある場合には、優先して合致させたいものを左に置いておく必要があります。
const regex = /foo|foooo/
"foooo".match(regex) // ["foo"]
const regex2 = /foooo|foo/
"foooo".match(regex2) // ["foooo"]
-
(?:)によるグループはカウントしません。 ↩