0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WebフロントエンドAdvent Calendar 2024

Day 13

正規表現とキャプチャグループ

Posted at

はじめに

正規表現を使用していると、パターン内の条件をまとめて扱いたい場面がでてくることがあります。
そのようなときにはキャプチャグループを利用すると簡潔に記述できるようになります。
また、キャプチャグループにマッチした文字列をパターンの後方で参照することもできます。

この記事ではキャプチャグループを利用した条件の書き方などについて見ていきたいと思います。

キャプチャグループ

グループ化は()で囲むことで行えます。
グループ化をすると、そのグループに対して{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"]
  1. (?:)によるグループはカウントしません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?