はじめに
正規表現を使用していると、パターン内の条件をまとめて扱いたい場面がでてくることがあります。
そのようなときにはキャプチャグループを利用すると簡潔に記述できるようになります。
また、キャプチャグループにマッチした文字列をパターンの後方で参照することもできます。
この記事ではキャプチャグループを利用した条件の書き方などについて見ていきたいと思います。
キャプチャグループ
グループ化は(
と)
で囲むことで行えます。
グループ化をすると、そのグループに対して{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"]
-
(?:)
によるグループはカウントしません。 ↩