(Excel)REGEXEXTRACT関数の使い方

REGEXEXTRACT関数の機能と構文

 REGEXEXTRACT関数の機能は「文字列中の、正規表現で表されるパターンにマッチする(あてはまる)部分を抽出する」というものです。
 構文は次の通りです([ ]は省略可)。

REGEXEXTRACT(対象文字列, 正規表現[, 抽出モード, 大・小文字の区別])

 正規表現では「[a-z]+」(1文字以上の半角英小文字という意味)とか「[0-9]{3}」(3文字の半角数字という意味)というように文字列の特徴を表すことができ、これにマッチする対象文字列中の部分が抽出されます。
 なお、正規表現にマッチする部分が複数ある場合でも最初の(最も文字列の先頭に近い)マッチ部分しか抽出されません。ただし第3引数の設定によりすべて抽出(複数セルにスピル)するといった設定が可能です。
 また、他の多くの関数と異なり大文字と小文字を区別します。これは正規表現のルールに基づくものですが、第4引数の設定により区別しないようにできます。

使用できる正規表現

 正規表現ではさまざまなメタキャラクタ(特別な記号)を使用して複雑な文字列のパターンを表現できます。
 以下の使用例でもその一部を使用していますが、REGEXEXTRACT関数等で使用できる正規表現の詳しい内容について次の記事で紹介していますのでご確認ください。

(Excel)REGEX~関数で使える正規表現 - いきなり答える備忘録


基本的な使用例

文字の種類と長さの指定

 まず正規表現のメタキャラクタ(特殊な文字)のうち、よく使われるものを紹介します。

記号意味
.任意の1文字
ワイルドカードの「?」に相当しますが、改行にはマッチしません
[abc]列挙した文字のうちいずれか1文字
(例はa,b,cのいずれか1文字という意味)
[a-z]指定した範囲のうちいずれか1文字
数字やひらがな、カタカナ等も同様に範囲指定ができます
(例はaからzまでの文字(英半角小文字)という意味)
abc|def指定した文字列(2文字以上可)のうちいずれか
(例はabcとdefのいずれかという意味)
[^abc]列挙した文字以外の1文字
(例はa,b,c以外の文字という意味)
[^a-z]指定した範囲以外の1文字
(例はaからzまでの文字(英半角小文字)以外の文字という意味)
¥n改行
¥エスケープ
(「¥.」は上記の定義による「任意の1文字」ではなく「.」の文字という意味)
*0回以上の繰り返し(なるべく長くマッチ)
+1回以上の繰り返し(なるべく長くマッチ)
{n}n回の繰り返し
*?0回以上の繰り返し(なるべく短くマッチ)

 これらの中で「.」や「[abc]」のように、ある文字を表すものを文字クラスといいます。
 「*」や「+」のように繰り返し回数(ある文字が何文字続くのか)を表すものを量指定子といいます。
 以下ではこれらを使った実例を紹介します。記事の後半では上記の表にないものも使いますが、その都度説明します。


 次の画像では、B列にいくつかの文字列が並んでいます。
 C列にREGEXETRACT関数を使った数式を入力して「『大』から始まる3文字」の部分を抽出しています。

 C3セル(下方にフィルコピー)

=REGEXEXTRACT(B3,"大..")

 正規表現で「.」は任意の1文字を意味します(ワイルドカードの「?」に相当)。
 よって「大..」は「『大』から始まる3文字」という意味になり、マッチ(該当)する部分が抽出されます。
 マッチする部分が複数ある場合は最初の(文字列の先頭に近い)ものが抽出されます(B3セル→C3セルの例)が、第3引数の設定によりすべて抽出することもできます(下記参照)。また、「大」の字があってもその後に2文字以上文字が続かないと何も抽出されずエラーとなります(B5セル→C5セル、B6セル→C6セルの例)。



 次の画像では、B列の文字列中の「『大』の字以降の部分」を抽出しています。

 C3セル(下方にフィルコピー)

=REGEXEXTRACT(B3,"大.*")

 正規表現で「*」は(直前で指定した文字の)「0回以上の繰り返し」という意味なので、「.*」は任意の文字が0文字以上という意味になります(ワイルドカードの「*」に相当)。よって「大」の字の後に何もない場合には「大」の字だけが抽出されます。



 次の画像では、文字列中の「S級」「A級」「B級」のいずれかに該当する部分を抽出しています。

 C3セル(下方にフィルコピー)

=REGEXEXTRACT(B3,"[SAB]級")

 「[SAB]」の部分がポイントです。このように[ ]で囲んだ中に文字を列記すると、そのいずれかの文字という意味になります。
 また、大文字と小文字が区別されるので「b級」は抽出されません(B6セル→C6セルの例)。ただし第4引数の設定で区別しないように変更することもできます(下記参照)。



 次の画像では、文字列中の「S級」「A級」「B級」以外の「〇級」という部分を抽出しています。

 C3セル(下方にフィルコピー)

=REGEXEXTRACT(B3,"[^SAB]級")

 [^ ]の中に文字を列記すると、それら以外の文字という意味になります。



 次の画像では文字列中の数字(半角数字)だけを抽出しています。

 C3セル(下方にフィルコピー)

=REGEXEXTRACT(B3,"[0-9]+")

 [ ]の中でハイフン(-)を使って文字の範囲を指定することができます。ただし文字の順序を守る必要があり「[9-0]」のように指定するとエラーになります。
 「+」は「1回以上の繰り返し(1文字以上)」という意味です。



 次の画像では、文字列中の「cats」「dogs」のいずれかに該当する部分を抽出しています。

 C3セル(下方にフィルコピー)

=REGEXEXTRACT(B3,"(cat|dog)s")

 「|」で区切ることでいずれかという意味になります。1文字の場合は上記例のように[ ]を使ってもいいですが2文字以上の場合はこちらを使います。
 また、カッコで囲むことで他の文字と連結させることができます。つまり「(cat|dog)s」は「cats|dogs」と同じ意味です。
 なおカッコには別の効果もあります(下記のグループ化とキャプチャの節参照)。

最長マッチと最短マッチ

 「*」(0回以上の繰り返し)や「+」(1回以上の繰り返し)の使用例を紹介しましたが、これらを使うと該当する文字が続く限り長くマッチしようとするので最長マッチと呼ばれます。一方で「*?」のようにすると(同じ0回以上の繰り返しでも)なるべく短くマッチしようとするので最短マッチと呼ばれます。
 説明だけだと意味が分かりにくいですが、注意すべき例を含めて補足となる事例をいくつか紹介します。


 次の画像では、最長マッチを使って文字列中の開きカッコ(全角)から閉じカッコ(全角)までを抽出しています。

 C3セル

=REGEXEXTRACT(B3,"(.*)")

 「.*」は「0文字以上の任意の文字」を意味しており、これを全角カッコで挟んでいます。
 「.*」がなるべく長くマッチするのならば文字列の最後まで抽出されるのでは、という気もしますが、それだとその次の「)」がどこにもあてはまらなくなってしまうので、そうはならないように抽出範囲の調整が図られます。結果的に開きカッコから閉じカッコまでが抽出されます。



 次の画像では同じ数式で、2つのカッコの組を含む文字列から抽出しようとしています。
 最初の閉じカッコまでを抽出するのが本来の意図だったのですが、2つ目の閉じカッコまで抽出されてしまっています。

 文字列中のカッコが1組のときはよかったのですが、「.*」が任意の文字(途中のカッコも含まれることに注意)になるべく長くマッチしようとするので結果的に最後の閉じカッコまで抽出されてしまいます。



 そこで次の画像では最短マッチを使って対応しています。

 C3セル

=REGEXEXTRACT(B3,"(.*?)")

 「.*?」を全角カッコで挟んでいます。「.*?」も「0文字以上の任意の文字」を意味しますが、条件を満たすうえでなるべく短いマッチで済ませようとします。
 この例(B6セル)では2文字目で最初の開きカッコが見つかり、その後6文字目で最初の閉じカッコが見つかるのでそれより先までマッチしようとはせず、そこまでしか抽出されないというわけです。



 この最短マッチも使いどころを誤ると意図しない結果となります。
 次の画像では文字列中のカッコが2重になっています。ここで上記例と同じ数式を使えば内側のカッコ内が抽出できるような気がしますが、結果は異なるものとなります。

 最初に見つかる開きカッコから最初に見つかる閉じカッコまでを抽出することとなるため、このような結果となります。
 最短マッチによりマッチが終了する位置を早めることはできるものの、マッチが開始される位置が遅れるわけではない、というのが注意点です。



 ではどうやって内側のカッコを抽出するかですが、次のようにするのが一例です。

 C3セル

=REGEXEXTRACT(B3,"([^()]*)")

 一気に難しくなります。
 「[^()]」の部分は「開きカッコでも閉じカッコでもない文字」という意味です。これに「*」を加えて0文字以上とし(ここでは「*?」と最短マッチにしなくてもOK)さらにカッコで挟んでいます。結果的に「両端がカッコで内側にカッコを含まない部分」が抽出されます。

 文字列の内容が限定されていれば(この例ではカッコの組が1つなら)そう難しくないですが、あらゆる文字列に対応しようとすると途端に難しくなることがあります。他の適当な関数が利用できればそちらを使うのが無難です。

アンカー(先頭・末尾)の使用例

 文字列の先頭を表す「^」と文字列の末尾を表す「$」の使用例です。
 REGEXTEST関数ではこれらを使って前方一致判定や後方一致判定ができますが、REGEXEXTRACT関数ではあまり使わないかもしれません。


 次の画像では、数字のうち文字列の先頭にあるものだけを抽出しています。

 C3セル(下方にコピー)

=REGEXEXTRACT(B3,"^[0-9]+")

 「^」は文字列の先頭の位置を意味します(「~以外」を表す[^ ]とは意味が異なるので注意)。よって「^[0-9]+」は文字列の先頭にある1文字以上の数字という意味になります。



 次の画像では、数字のうち文字列の末尾にあるものだけを抽出しています。

 C3セル(下方にコピー)

=REGEXEXTRACT(B3,"[0-9]+$")

 「$」は文字列の末尾の位置を意味します。よって「[0-9]+$」は文字列の末尾にある1文字以上の数字という意味になります。



 次の画像では文字列全体が数字だけからなるものを抽出しています。

 C3セル(下方にコピー)

=REGEXEXTRACT(B3,"^[0-9]+$")

 「^」と「$」の両方を使っています。つまり「数字で始まり数字で終わる」という意味になるので数字以外の文字を含んでいると抽出されません。
 わざわざREGEX~関数を使って「^りんご$」のような完全一致判定(抽出)をしてもあまり意味はありませんが、このように一定の形式を満たしているかチェックするために「^」と「$」の両方を使うのは有効な利用例と考えられます。

グループ化とキャプチャの使用例

 すでに1つの例を紹介していますが、正規表現を半角カッコで囲むことで、その部分を1つのかたまりとして扱うことができます。
 これにより上記例の「(cat|dog)s」のように共通する部分(s)とそうでない部分を分けて表記できるほか、囲まれた部分全体を量指定子による繰り返しの対象とすることができます。
 このほか、第4引数の設定により正規表現に該当する文字列のうちさらに一部を抽出することができます。また、正規表現にマッチする部分の内容を番号を使って参照できる効果(キャプチャ)があります。


 まずは量指定子との併用例です。
 次の画像では「ミニ」が2回以上連続し、その次に「ライブ」が続く部分を抽出しています。

 C3セル(下方にコピー)

=REGEXEXTRACT(B3,"(ミニ){2,}ライブ")

 「{2,}」は「2回以上の繰り返し」という意味です。その前の「ミニ」をカッコで囲んでいるのでこの2文字が繰り返しの対象となります。カッコがないと「二」だけが繰り返しの対象となります。



 以下で紹介する内容の先取りとなりますが、次の画像は第4引数と併用して、右側に「円」が続くような数字だけを抽出しています。

 C3セル(下方にコピー)

=REGEXEXTRACT(B3,"([0-9]+)円",2)

 第4引数を「2」とすることで正規表現(第2引数)にマッチする部分のうち、グループ化されている部分(数字)だけが抽出されます。
 


 次の画像はキャプチャの例です。
 次の画像では同じ文字が2文字連続する部分を抽出しています。

 C3セル(下方にコピー)

=REGEXEXTRACT(B3,"(.)\1")

 「(.)」で任意の1文字をグループ化しています。これにマッチする文字列には「¥1」という番号が与えられ、変数のように参照することができます(数式バーでは上記の欄のようにバックスラッシュとして表示されるので注意)。
 つまり「(.)¥1」は「任意の1文字と、その同じ文字が続く2文字の部分」という意味になります。
 なおグループ化を複数行うと2番目以降には「¥2」「¥3」…の番号が与えられます。



 次の画像では2文字以上の文字が2回以上繰り返される部分を抽出しています。

 C3セル(下方にコピー)

=REGEXEXTRACT(B3,"(.+)\1+")

 上記例との違いは「+」(1回以上の繰り返し)を2か所使用していることです。このように「¥1」にも量指定子を使える点がポイントです。

先読みと後読みの使用例

 簡単に言うと「右側に~が接している」(肯定先読み)とか「左側に~が接している」(肯定後読み)といった条件付けができます。否定先読み(~が接しない)というのもありますが、ここでは肯定読みの簡単な例だけ紹介します。より詳しくは参考記事をご覧ください。
 また、グループ化と第4引数の設定で同じことができるケースも多いのでそちらもご確認ください。


 まずは肯定先読みの例です。
 次の画像では、文字列中の数字のうち「円」が右側(末尾側)に接しているもの(つまり「円」の左にある数字)を抽出しています。

 C3セル(下方にコピー)

=REGEXEXTRACT(B3,"[0-9]+(?=円)")

 「(?=円)」の部分が肯定先読みと呼ばれる部分です。これにより文字列に条件を課しつつ、その部分を抽出対象から除くことができます。



 なお、同様の数字をすべて抽出する場合は次のようにします(B4セル→C4:E4セルの例参照)。

 C3セル(下方にコピー)

=REGEXEXTRACT(B3,"[0-9]+(?=円)",1)

 以下で紹介する内容の先取りになりますが、第3引数を「1」とすることで正規表現にマッチする部分をすべて(複数)取得できます。
 対象となる部分(~円)が1つしかない場合や一定の形式の文字列に一定数含まれる場合は、グループ化して第3引数=2と指定する方法もあります(以下の第3引数の節で紹介しています)。



 次の画像は肯定後読みの例です。
 文字列中の、「@」が左側(先頭側)に接している部分(つまり@より後の部分全体)を抽出しています。

 C3セル(下方にコピー)

=REGEXEXTRACT(B3,"(?<=@).*")

 「(?<=@)」の部分が肯定後読みと呼ばれる部分です。
 なお、1つ上の例と異なり量指定子が「*」(0回以上)なので「@」の後に何もない場合に空文字列が抽出されます(B5セル→C5セルの例)。

第3引数(抽出モード)の効果

 上記の例でもみたように、正規表現のパターンにマッチする部分が複数あるとしても基本的に最初の(先頭に近い)1つの部分しか抽出されませんが、これを第3引数の指定により変更することができます。
 設定できる値は次の通りです。

効果
0最初にマッチする部分を抽出(既定値)
1マッチする部分をすべて抽出
2最初にマッチする部分のうちグループ化されている部分をすべて抽出


 第3引数を「0」とした場合または省略した場合は最初の(先頭に近い)1つの部分しか抽出されません。つまりデフォルトは「0」です。
 次の画像ではあえて「0」を指定し、文字列中の半角数字のうち最初の部分だけを抽出してます。

 C3セル

=REGEXEXTRACT(B3,"[0-9]+",0)

 


 次の画像では第3引数を「1」とし、すべての数字を抽出しています。
 複数の数字が複数のセルに分けて抽出されます(スピル)。

 C3セル

=REGEXEXTRACT(B3,"[0-9]+",1)

 「+」がないと1文字ずつの数字に分割されて抽出(11個の数字が11セルに分割)されることとなります。



 次の画像は文字列を1文字ずつ分割する例です。

 C3セル

=REGEXEXTRACT(B3,".",1)

 「.」は任意の1文字にマッチするので、第3引数を「1」とすることで文字列が1つ1つの文字に分割されて抽出されることとなります。



 第3引数を「2」とすると、グループ化した(カッコで囲んだ)部分にマッチする部分をすべて抽出します。
 第2引数(正規表現)にグループ化している部分がないとエラーになります

 C3セル(下方にフィルコピー)

=REGEXEXTRACT(B3,"^([A-Z]{2})(\d{3})-(\d{3})$",2)

 ちょっと複雑ですが「([A-Z]{2})(\d{3})-(\d{3})」の部分は「英半角大文字2文字-半角数字3文字-半角数字3文字」を表しています(「¥d」は「[0-9]」に相当します)。
 カッコを使って①英字2字の部分②数字3字の部分のうち1つ目③数字3字の部分のうち2つ目、というように3つのグループを設定しており、そして第3引数を「2」とすることでそれらを抽出しています。
 なお、「^」と「$」を使うことで完全一致(的な)判定にしているので、余分な文字が入っていると何も抽出されません(B7→C7セルの例)。



 ところで、次の画像のような例では注意が必要です。

 C3セル(下方にフィルコピー)

=REGEXEXTRACT(B3,"([0-9]+)円",2)

 グループ化を利用して第4引数を「2」とすることで「円」の左側にある数字がすべて抽出されるようにも思われますが、B3セル→C3セルを見るとデフォルトと同じく、1つの数字しか抽出されていないことがわかります。
 これは正規表現(第2引数)にマッチする部分を1つだけ取り出し、その中に含まれるグループをすべて抽出するようになっているからです。関数の入力中のヘルプで「2-最初の一致のグループをキャプチャする」と表示される理由も1つ上の例とこの例から理解できると思います。
 なお、実際に数字をすべて抽出する方法については先読みと後読みの例で紹介しています。

第4引数(大・小文字の区別)の効果

 REGEXETRACT関数では(たいていのExcel関数と異なり)基本的に正規表現の大文字と小文字を区別します。ただし第4引数を使ってこれを変更できます。
 設定できる値は次のとおりです。

効果
0大文字と小文字を区別する(既定値)
1大文字と小文字を区別しない


 第4引数を「0」とした場合または省略した場合は大文字と小文字を区別します。つまりデフォルトは「0」です。
 次の画像ではあえて「0」を指定し、文字列中の半角英小文字の部分だけを抽出してます。B4セル→C4セルの例では単語中の最初の大文字だけ抽出されていないことに注意してください。

 C3セル(下方にフィルコピー)

=REGEXEXTRACT(B3,"[a-z]+",,0)

 


 次の画像では第4引数を「1」とし、大文字と小文字を区別せずに抽出しています。

 C3セル(下方にフィルコピー)

=REGEXEXTRACT(B3,"[a-z]+",,1)

 正規表現で小文字を使ったからといって、すべて小文字で抽出されるわけではありません。もとの文字列中の表記のまま抽出されます。