REGEXREPLACE関数の機能と構文
REGEXREPLACE関数の機能は「文字列中の、正規表現で表されるパターンにマッチする(あてはまる)部分を別の文字列に置き換える」というものです。
構文は次の通りです([ ]は省略可)。
REGEXREPLACE(対象文字列, 正規表現, 置換先文字列[, 置換対象, 大・小文字の区別])
正規表現では「[a-z]+」(1文字以上の半角英小文字という意味)とか「[0-9]{3}」(3文字の半角数字という意味)というように文字列のパターン(特徴)を表すことができます。REGEXREPLACE関数では対象文字列中のうちこのパターンにマッチする部分を置換先文字列に置き換えることができます。
置換先文字列として空文字列("")を指定したり何も指定しない(引数の区切りのカンマだけ入れる)と結果的にその部分を削除することができます。
正規表現にマッチする部分が複数ある場合はすべてのマッチする部分が置き換えられます。ただし第4引数の設定によりマッチする部分のうち特定のもの(〇番目)だけを置き換えさせることができます。
また、他の多くの関数と異なり大文字と小文字を区別します。これは正規表現のルールに基づくものですが、第5引数の設定により区別しないようにできます。
使用できる正規表現
正規表現では通常の英数字や漢字ひらがな等の文字と、さまざまなメタキャラクタ(特別な記号)を使用して文字列のパターンを表現できます。
以下の使用例でもその一部を紹介していますが、REGEXREPLACE関数等で使用できる正規表現の詳しい内容について次の記事で紹介していますのでご確認ください。
(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]」のように、ある文字を表すものを文字クラスといいます。
「*」や「+」のように繰り返し回数(ある文字が何文字続くのか)を表すものは量指定子といいます。
以下ではこれらを使った実例を紹介します。上記の表にないものも使いますが、その都度説明します。
まず、次の画像ではC列にREGEXREPLACE関数を使った数式を入力し、B列の文字列中の「市」の字とその前の2文字(合計3文字)を「〇〇市」に置き換えています(伏字にする例)。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"..市","〇〇市")
「.」は正規表現で任意の1文字を表します(ワイルドカードの「?」に相当)。よって「..市」は「『市』で終わる3文字」という意味になり、マッチ(該当)する部分が置き換えられます。該当する部分はすべて置き換えられます(B4セル→C4セルの例)。
「市」の字の前に2文字以上ないとマッチしないので置き換えられません(B5→C5セルの例)。また、特に注意すべきなのはB6→C6セルの例で、「葉県市」の3文字が置き換えられる一方で、その右側に残るのが「川市」の2文字だけなのでこの部分が正規表現にマッチせず、置き換えられません。
次の画像では、B列の文字列中の「市」の字より右側の部分を削除しています。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"市.*","市")
正規表現で「*」は(直前で指定した文字の)「0回以上の繰り返し」を意味するので、「.*」は任意の文字が0文字以上という意味です(ワイルドカードの「*」に相当)。
なお、第3引数の設定によってはこのように文字列の一部を削除することができます。文字列中の必要な部分を取得するときにREGEXEXTRACT関数を使って正規表現に必要な部分を抽出するか、REGEXREPLACE関数を使って必要でない部分を削除するかというのは案外迷うところです。
次の画像では、文字列中の「S判定」「A判定」「B判定」のいずれかに該当する部分を「高評価」に置き換えています。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"[SAB]判定","高評価")
角カッコ([ ])の中に文字を列記すると、それらの文字のいずれかという意味になります。
なお、大文字と小文字が区別されるので「b判定」は置き換えられません(B6セル→C6セルの例)。これは第5引数の設定により区別しないように変更することもできます(下記参照)。
次の画像では、「S」「A」「B」の3文字以外の文字と「判定」が並ぶ計3文字の部分を「低評価」に置き換えています。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"[^SAB]判定","低評価")
「[^ ]」の内側に文字を列記することで、それら以外の文字という意味になります。
次の画像では、文字列中の「今ひとつ」「今一つ」「いま一つ」を「いまひとつ」に置き換えています(表記ゆれ修正)。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"(今ひと|今一|いま一)つ","いまひとつ")
「|」で区切ることでいずれかの文字(文字列)という意味になります。1文字の場合は上記例のように[ ]を使ってもいいですが2文字以上の場合はこちらを使います。また、カッコで囲むことで他の文字と連結させることができます。「(今ひと|今一|いま一)つ」は「今ひとつ|今一つ|いま一つ」と同じ意味です。
なお、カッコには別の効果もあります(グループ化とキャプチャの節参照)。
次の画像では、文字列中の数字(半角数字)を1文字ずつ「x」に置き換えています(伏字にする例)。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"[0-9]","x")
「[0-9]」は0から9までの半角数字という意味です。このように[ ]の中でハイフン(-)を使うことで文字の範囲を指定できます(1つ1つ列記する必要がなくなる)。ただし指定の順序に決まりがあり「[9-0]」のように指定するとエラーになります。
次の画像でも文字列中の数字を「x」に置き換えていますが、ここでは1かたまりの数字を1文字の「x」に置き換えています。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"[0-9]+","x")
「+」は1回以上の繰り返しという意味です。よって「[0-9]+」は1文字以上の数字(が並んでいる部分)という意味になります。
1つ上の例だと数字を伏せても桁数がわかってしまいますが、こちらの例では伏字の長さを固定することができます。
次の画像では、文字列中の「⇒」と改行が並ぶ部分を「~」に置き換えています。

C3セル
=REGEXREPLACE(B3,"⇒\n","~")
正規表現で「¥n」は改行を意味します。CHAR(10)も使えますがこの例では「"⇒"&CHAR(10)」のようにしなければならず面倒になります。
最長マッチと最短マッチ
上記の例で紹介した「*」(0回以上の繰り返し)や「+」(1回以上の繰り返し)のような量演算子は、該当する文字が続く限り長くマッチしようとするので最長マッチと呼ばれます。また、「*?」などは(同じ0回以上の繰り返しでも)なるべく短くマッチしようとするので最短マッチと呼ばれます。
これらはとても便利なのですが難しい部分でもあるので、補足事例をいくつか紹介します。
次の画像では最長マッチを使って文字列中の開きカッコ(全角)から閉じカッコ(全角)までを空文字列に("")に置き換え、結果的に削除しています。

C3セル
=REGEXREPLACE(B3,"(.*)","")
「.*」は「0文字以上の任意の文字」で、これを全角カッコで挟んでいます。「.*」はなるべく長くマッチする、つまり基本的には文字列の最後までマッチしようとするわけですが、この部分が文字列の最後までマッチしてしまうとその右の「)」がどこにもマッチしなくなってしまうので、そうはならないようにマッチ部分が調整されます。結果的に第2引数の「(.*)」は「(おうめ)」にマッチすることとなり、開きカッコから閉じカッコまでが抽出されます。
次の画像では同じ数式で、2つのカッコの組を含む文字列のカッコ間を削除しようとしています。
2組の開きカッコから閉じカッコまでをそれぞれ削除するというのが本来の意図だったのですが、より長い部分が削除されてしまっています。

上記例と同じように「.*」がなるべく長くマッチするように調整されます。これにより第2引数の「(.*)」が「(おうめ)駅から拝島(はいじま)」にマッチするのでこうなります。第2引数(正規表現)をこのような文字列にしたときに「.*」の部分がカッコにマッチしないものと錯覚しやすいのが注意点です。
そこで、次の画像では最短マッチを使って2組のカッコ間だけを削除しています。

C3セル
=REGEXREPLACE(B3,"(.*?)","")
ここでは「.*?」をカッコで挟んでいます。「.*?」も「0文字以上の任意の文字」を意味しますが、マッチする部分がなるべく短くなるように調整されます。
第2引数の「(.*?)」は「(おうめ)」と「(はいじま)」にマッチすることになり、それより短くマッチさせることはできません。結果的にこの2つの部分がが削除されます。
しかしこの最短マッチも場合によっては意図しない結果となることがあります。
次の画像では文字列中のカッコが2重になっています。ここで上記例と同じ数式により内側のカッコ内が抽出できるように思われますが、異なる結果となります。

上記例でみたように最短マッチを使うことでマッチが終了する位置を早めることができるのですが、マッチの開始位置を遅らせることはできない、つまり第2引数中の「(」が文字列中の最初の「(」にマッチすることには変わりがない、というのが注意点です。よって第2引数中「(.*?)」は「(青梅(おうめ)」にマッチすることになり、この部分が削除されることとなります。
このような文字列から内側のカッコ内を削除する場合、次のようにするのが一例です。

C3セル
=REGEXREPLACE(B3,"([^()]*)","")
「[^()]」の部分は「開きカッコでも閉じカッコでもない文字」という意味です。これに「*」を加えて0文字以上とし(ここでは「*?」と最短マッチにしなくてもいいです)、カッコで挟んでいます。つまり「両端がカッコで内側にカッコを含まない部分」が削除されます。
アンカー(先頭・末尾・文字間)の使用例
文字列の先頭である「^」と、文字列の末尾である「$」の使用例です。両方を使うことにより完全一致(それ以外の文字を含まない)する文字列を置換の対象にすることもできます。
このほかに空文字列("")を使うと、すべての文字のない部分(先頭・末尾・文字の間)を置き換えの対象にすることができます。
次の画像では、半角数字のうち文字列の先頭にあるもの(「数字のうち最初のもの」ではないので注意)だけを「x」に置き換えています。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"^[0-9]+","x")
「^」だけだと文字列の先頭の意味になります(後で見るように単体で置き換え対象にすることもできます)。その右に「[0-9]+」を並べることで文字列の先頭にある数字の部分という意味になります。
次の画像では、数字のうち文字列の末尾にあるものだけを「x」に置き換えています。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"[0-9]+$","x")
「$」だけだと文字列の末尾の意味になりますが、その左に「[0-9]+」を並べることで文字列の末尾にある数字の部分という意味になります。
次の画像では、文字列全体が数字であるものだけを「x」に置き換えています。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"^[0-9]+$","x")
上の2つの例から予想できますが、「[0-9]+」を「^」と「$」で挟むことで「数字で始まり数字で終わる」という意味になります。
よって数字だけからなる文字列が置換の対象となります。
次の画像では、文字列の先頭や末尾、文字間をそれぞれ「★」に置き換えています。
3つのセルでそれぞれ違う式を使っているので注意してください。

C3セル
C4セル
C5セル
=REGEXREPLACE(B3,"^","★") =REGEXREPLACE(B4,"$","★") =REGEXREPLACE(B5,"","★")
「^」や「$」を置換対象とすることで、先頭や末尾に加えることができます。置き換え後の文字列から「^」や「$」がなくなる(マッチしなくなる)ということはなく、実際にREGEXREPLACE関数をネストすればさらに文字を加えることができます。
「""」については特に正規表現のメタキャラクタという扱いはされていないようですが、このように文字列の先頭・末尾・文字間のすべてを操作(置換)対象にすることができます。なお、文字の間だけに文字を挿入する例については先読みと後読みの例で紹介しています。
グループ化とキャプチャの使用例
すでに最初の節で紹介していますが、正規表現を半角カッコで囲むことで、その部分を1つのかたまりとして扱うことができます。
これにより上記例の「(今ひと|今一|いま一)つ」のように共通する部分(「つ」の字)とそうでない部分を分けて表記できるほか、囲まれた部分全体を量指定子による繰り返しの対象とすることができます。
また、正規表現にマッチする部分の内容を変数のように参照できる効果(キャプチャ)があります。
はじめに量指定子との併用例です。
次の画像では「もふ」が2回以上連続し、その次に「映像」が続く部分を「モフモフ動画」に置き換えています。「もふ映像」では置き換えられませんし、「もふもふ」の右が「映像」でないと置き換えられません。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"(もふ){2,}映像","モフモフ動画")「{2,}」は「2回以上の繰り返し」という意味です。その前の「もふ」をカッコで囲んでいるのでこの2文字が繰り返しの対象となります。このカッコがないと「ふ」だけが繰り返しの対象となります。
次はキャプチャの例です。
ここではキャプチャを利用して半角数字の右側に「円」の字を加えています。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"([0-9]+)","\1円")
グループ化(カッコで囲む)した正規表現にマッチする文字列(ここでは数字の部分)は、「¥1」という番号で参照することができます。
そこで第3引数(置換先文字列)を「¥1円」とすることにより、数字の部分に「円」を加えることができるというわけです。複数のグループ化を行った場合、それらは「¥2」「¥3」…で参照できます。
次の画像では、半角数字の右側に「円」が続く部分のうち「円」を削除しています。
左側に数字がない「円」はそのままになります(B5セルの1文字目及びB6セルの例)。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"([0-9]+)円","\1")
グループ化することで数字の部分に「¥1」という番号を与えたうえで、「¥1円」つまり「数字と『円』が並ぶ部分」を、「¥1」つまり数字だけに置き換えています。
第2引数内で番号を使って文字列を参照することもできます。
次の画像では、2文字以上の文字列が2回繰り返されている部分の繰り返しを除き、1回だけにしています。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"(.+)\1+","\1")
「(.+)」は1文字以上の任意の文字列で、グループ化しているので「¥1」で参照できます。
その直後に「¥1+」を加えることで、全体としてその任意の文字列が2回以上繰り返されている部分を表しています。
第3引数の「¥1」は、その2回以上の繰り返しの1回分にあたります。これにより同一の文字列の2回以上の繰り返しが1回だけに置き換えられます。
先読みと後読みの使用例
簡単に言うと「右側に~が接している」(肯定先読み)とか「左側に~が接している」(肯定後読み)といった条件を設定できます。否定先読み(~が接しない)というのもあります。
特にREGEXREPLACE関数では他の機能で代替できるケースが多いので、肯定読みの簡単な例だけ紹介します。もしかしたら否定読みの方が有用かもしれませんが、詳しくは参考記事をご覧ください。
はじめに肯定先読みの例です。
次の画像では、文字列中の数字のうち「円」が右側(末尾側)に接している数字の部分(つまり「円」の左にある数字)を「x」に置き換えています。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"[0-9]+(?=円)","x")
「(?=円)」の部分が肯定先読みという部分です。これにより文字列に条件を課しつつ、その部分を置換対象から除くことができます。
ただしグループ化とキャプチャでも同じようにできます(上記例参照)。
次の画像は肯定後読みの例です。
文字列中の、「県」が左側(先頭側)に接している部分(つまり「県」より後の部分全体)を削除しています。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"(?<=県).*","")
これも「県.*」を「県」に置き換えれば済むのでさほど実用的ではないです。
少し変わった例として、次の画像では文字列中の各文字の間に「★」を挿んでいます。

C3セル
=REGEXREPLACE(B3,"(.)(?=.)","\1★")
「(?=.)」が肯定先読みの部分で、「右側に任意の1文字が続く」という条件になっています。
さらにグループ化とキャプチャを併用し「右側に文字が続くような文字」を「その文字と★」にそれぞれ置き換えています。
なお、次のようにしても同じ結果となります。
=REGEXREPLACE(B3,"(?<=.)(?=.)","★")
先読みと後読みを両方使い、右にも左にも文字があるような部分(文字の間)を「★」に置き換えています。
第4引数(置換対象)の効果
REGEXREPLACE関数では基本的に正規表現にマッチする部分がすべて置き換えられます。ただし第4引数を使ってこれを変更できます。
設定できる値は次のとおりです。
| 値 | 効果 |
|---|---|
| 0 | 正規表現にマッチするすべての部分を置き換える(既定値) |
| 1,2,3… (プラスの数値) | 正規表現にマッチする部分のうち〇番目の部分を置き換える |
| -1,-2,-3… (マイナスの数値) | 正規表現にマッチする部分のうち後ろから〇番目の部分を置き換える |
マイナスの数値の指定(後ろから〇番目を置換)はSUBSTITUTE関数にはない仕様で、正規表現を使う必要がない場合でもREGEXREPLACE関数を使う理由になります。
第4引数を「0」とした場合または省略した場合は、正規表現にマッチする部分がすべて置き換えられます。つまりデフォルトは「0」です。
次の画像ではあえて「0」を指定し、文字列中の半角数字の部分をすべて「x」に置き換えています。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"[0-9]+","x",0)
次の画像では第4引数を「3」とし、数字の部分のうち3番目のものだけを「x」に置き換えています。
これまでの例と同様に、該当する部分がない場合は文字列は何も変わりません。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"[0-9]+","x",3)
「{1,3}」のようにすれば1番目と3番目を置き換えられるかも…という気もしますが、そうはなりません(別々のセルに別々の結果が出力されます)。
次の画像では第4引数を「-1」とし、数字の部分のうち最後のものだけを「x」に置き換えています。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"[0-9]+","x",-1)
第5引数(大・小文字の区別)の効果
REGEXREPLACE関数では基本的に正規表現の大文字と小文字を区別します。ただし第5引数を使ってこれを変更できます。
設定できる値は次のとおりです。
| 値 | 効果 |
|---|---|
| 0 | 大文字と小文字を区別する(既定値) |
| 1 | 大文字と小文字を区別しない |
第5引数を「0」とした場合または省略した場合は大文字と小文字を区別します。つまりデフォルトは「0」です。
次の画像ではあえて「0」を指定し、文字列中の半角英小文字の部分だけを置き換えています。具体的にはグループ化とキャプチャ(¥1)を使って半角英小文字の前後にカギカッコを加えています。
B4セル→C4セルの例では単語中の最初の大文字がカギカッコから外れていることに注意してください。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"([a-z]+)","「\1」",0)
次の画像では第5引数を「1」とし、大文字と小文字を区別せずに置き換えています。

C3セル(下方にフィルコピー)
=REGEXREPLACE(B3,"([a-z]+)","「\1」",,1)
この例だと第5引数を使わず「([a-z]+)」を「([a-zA-Z]+)」に代えても同じ結果になるのでそちらの方が使いやすいかもしれません。
ただし「apple」を「APPLE」のほか「Apple」にもマッチさせるとか、セルに入力された値を検索値として利用するケースでは便利です。