(Excel)REGEXTEST関数の使い方

REGEXTEST関数の機能と構文

 REGEXTEST関数は、文字列が正規表現で表されるパターンにあてはまるかどうか、正確には当てはまる(マッチする)部分を含むかどうか判定し、含む場合はTRUEを、そうでない場合はFALSEを返します。
 構文は次の通りです([ ]は省略可)。

REGEXTEST(対象文字列, 正規表現[, 大・小文字の区別])

 繰り返しになりますが判定は正規表現のパターンにあてはまる部分を含むかどうか、つまり部分一致で行われます。一例として正規表現では「.」が任意の1文字を表します(ワイルドカードの「?」に相当)が、部分一致判定されることにより対象文字列(第1引数)が1文字の場合だけでなく、2文字以上であってもその中の1文字が「.」にマッチするものとみなされます。よって「=REGEXTEST("こんにちは",".")」という式の結果はTRUEになります。
 基本的に大文字と小文字を区別します。これは正規表現のルールに基づくものですが、第3引数を「1」とすることで区別しないようにすることができます(0ないし省略した場合に区別されます)。
 もう1つの特徴として、正規表現として「""」(空文字列。長さ0の文字列)を指定したり何も指定しない場合、どのような対象文字列にも(空白セルに対しても)TRUEを返します。正規表現ではこれが文字列の先頭や末尾、文字の間にマッチするという理由に基づきます。


使用できる正規表現

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

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

基本的な使用例

部分一致(~を含む)判定

 次の画像では、B列の文字列が「山」の字を含んでいるかを判定しています。含む場合はTRUE、含まない場合はFALSEと判定されます。

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

=REGEXTEST(B3,"山")

 上でも述べましたが、REGEXTEST関数の判定は部分一致判定で行われるので、メタキャラクタ(特別な文字)を使わなくても部分一致判定になります。



 次の画像では、B列の文字列が半角数字を含んでいるか判定しています。

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

=REGEXTEST(B3,"[0-9]")

 「[0-9]」は0から9までの半角数字という意味です(「¥d」でも同じ意味になります)。
 ワイルドカードでは一定の文字の種類や範囲を指定するということができませんが、このように指定できるのが正規表現の特徴です。

前方一致(~で始まる)判定

 次の画像では、B列の文字列が「山」の字で始まるかを判定しています。

 C3セル(下方にコピー)

=REGEXTEST(B3,"^山")

 「^」は正規表現で文字列の先頭を表すので、「^山」は「先頭の『山』」という意味になります(より正確に言うと先頭と「山」の字が並んでいる部分という意味)。
 ワイルドカードだと「山*」となりますが、記号が付く位置が前後逆になるので注意してください。

後方一致(~で終わる)判定

 次の画像では、B列の文字列が「県」の字で終わるかを判定しています。

 C3セル(下方にコピー)

=REGEXTEST(B3,"県$")

 「$」は正規表現で文字列の末尾を表すので、「県$」は「末尾の『県』」という意味になります(より正確に言うと「県」の字と末尾が並んでいる部分という意味)。
 ワイルドカードだと「*県」となりますが、やはり記号が付く位置が逆になります。

完全一致判定にする場合

 上記の例から推測できるように、第2引数を「"^山形県$"」とか「"^りんご$"」とすれば完全一致判定(意図する文字列以外を含まない)ができます。
 ただしREGEXTEST関数でこのような判定をする主な目的は、文字列が所定の形式になっているかを判定するというものです。
 具体例は次のようになります。

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

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

 「[A-Z]」は半角大文字を、「¥d」は半角数字(「[0-9]」と同じ意味。シート上では¥がバックスラッシュになるので注意)を、「{n}」は直前の文字のn個の繰り返しを表します。これらとハイフンを使って所定の形式(半角大文字2字-半角数字3字-半角数字4字)を表し、前後に「^」と「$」をつけることで完全一致判定としています。

FILTER関数での条件指定の例

 REGEXTEST関数は判定結果をTRUE/FALSEで返すので、IF関数に組み込んで○×表示させるといったことができますが、他にはFILTER関数の抽出条件にするという使い方があります。
 次の画像では、表のデータ(B~D列)のうち、B列の文字列が「山」を含むものを抽出しています。

 F3セル

=FILTER(B3:D7,REGEXTEST(B3:B7,"山"))

 ある文字列に対する部分一致・前方一致・後方一致の判定はCOUNTIF関数+ワイルドカードでも可能ですが、COUNTIF関数の機能は「該当する値をカウントする」というものであるためFILTER関数の条件として用いるのに適していません(各文字列を個別に判定した配列を返せないため)。
 しかしREGEXTEST関数の場合は各文字列が条件に該当するかどうか(TRUE/FALSE)の配列を返すことができるので、このようにFILTER関数の条件指定に用いるというのが代表的な使用例となっています。

「含まない」等の判定方法

 NOT関数を使う方法と正規表現で実現する方法の2つの方法を紹介します。
 正規表現による方法は複雑になりますのでNOT関数の方が無難です。


 まずNOT関数を使う方法です。次の画像では、B列の文字列が「山」を含まないかどうかを判定しています。
 含まない場合はTRUE、含む場合はFALSEと判定されます。

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

=NOT(REGEXTEST(B3,"山"))

 「REGEXTEST(B3,"山")」の部分は「~を含む」の例と同じですが、NOT関数を使ってTRUE/FALSEの判定結果を反転させています。
 IF関数のようにTRUE/FALSEに応じた結果を表示させる場合はこのような方法は必須ではありません(第2引数と第3引数の表示内容を適宜指定すればいいだけ)が、FILTER関数で「含まないものを抽出する」といった場合にこのような方法が必要になります(以下で紹介するAND/OR関数の例と異なり第2引数を「B3:B7」のように拡張したときに配列を返すのでFILTER関数の条件に使えます)。

 なお「『山』で始まらない」は「=NOT(REGEXTEST(B3,"^山"))」、「『県』で終わらない」は「=NOT(REGEXTEST(B3,"県$"))」という式になります。



 次は正規表現を使う方法です。正規表現そのもので「含まない」の条件を指定しています。

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

=REGEXTEST(B3,"^(?!.*山)")

 一気に難しくなりますが正規表現の否定先読みという機能を使っています。
 「^」は文字列の先頭を、「(?!~)」は「次(末尾側)に~が続かない」という意味を、そして「.*」は任意の0文字以上の文字を表します。つまりこの正規表現(第2引数)は「先頭の後に、0文字以上の文字と『山』が続かない」、結局は「山」を含まないという意味になります。
 以下の例でも示すように正規表現では「[^山]」とすることで「『山』以外の文字」という意味になります([ ]の中では「^」の意味が異なるので注意)が、「=REGEXTEST(B3,"[^山]")」とするのは誤りです。これでは文字列が「山」以外の文字を含むとTRUEになるからです。

 また、「『山』で始まらない」は「=REGEXTEST(B3,"^(?!山)")」、「『県』で終わらない」は否定後読みを使って「=REGEXTEST(B3,"(?<!県)$")」となります。
 この例では条件が1文字だけなのでそれぞれ「=REGEXTEST(B3,"^[^山]")」、「=REGEXTEST(B3,"[^県]$")」とできます(「[^山]」は山以外の1文字、[^県]は県以外の1文字の意味)。ただしこの記し方では「『山県』で終わらない」といったような2文字以上の条件には拡張できません。

複数条件で判定する方法

AND条件(かつ)の場合

 対象文字列(第1引数)が複数の条件をすべて満たすかどうか判定する方法についてです。
 3つの方法を紹介します。


 まずはAND関数を使う方法です。
 B列の文字列が「A」と「B」の両方を含むかどうかを判定しています。

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

=AND(REGEXTEST(B3,"A"),REGEXTEST(B3,"B"))

 AND関数により、2つのREGEXTEST関数の結果が両方TRUEである場合にTRUEに、そうでない場合はFALSEが返されます。
 わかりやすいのですが、対象範囲を「B3:B7」のように拡張しても1つの値しか得られない(すべてのセルがAとBを含む場合にTRUE、そうでない場合にFALSEを返す)のでFILTER関数の条件指定には使えません



 続いて「*」演算を使う方法です。
 ここでもB列の文字列が「A」と「B」の両方を含むかどうかを判定しています。

 C3セル

=REGEXTEST(B3,"A")*REGEXTEST(B3,"B")=1

 それぞれのREGEXTEST関数の結果について、TRUEを1とみなしFALSEを0とみなす掛け算が行われます。
 両方のREGEXTEST関数の結果がTRUEの場合(つまり「A」と「B」の両方を含むとき)は掛け算の結果は1となるので「=1」を含めた式全体の結果はTRUEとなり、それ以外の場合は掛け算は0となるので式全体の結果はFALSEとなります。
 ちょっと難しいですが対象範囲を「B3:B7」のように拡張したときに各セルを判定した配列が得られるのでFILTER関数の条件指定に使えます。このとき「=1」は省略できます(0以外の数値がTRUE、0がFALSEとみなされるため)。



 3つ目は正規表現そのもので指定する方法です。

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

=REGEXTEST(B3,"^(?=.*A)(?=.*B)")

 これも難しくなりますが正規表現の肯定先読みを使っています。
 「^」は文字列の先頭を、「(?=~)」は「次(末尾側)に~が続く」という意味を、そして「.*」は任意の0文字以上の文字を表します。この正規表現(第2引数)は「先頭の後に、0文字以上の文字と『A』が、同様に0文字以上の文字と『B』が続く」、結局は「A」と「B」を含むという意味になります。
 これもFILTER関数の条件に使えます。



 次の画像も正規表現を使う例で、「A」も「B」も含まない、という判定をしています。

 C3セル

=REGEXTEST(B3,"^(?!.*A)(?!.*B)")

 正規表現の否定先読み「(?!~)」は、「次(末尾側)に~が続かない」という意味です。
 後は1つ上の例と同様です。

OR条件(または)の場合

 対象文字列(第1引数)が複数の条件のいずれかを満たすかどうか判定する方法についてです。
 3つの方法を紹介します。


 1つ目はOR関数を使う方法です。
 B列の文字列が「A」か「B」のいずれかを含むかどうかを判定しています。

 C3セル

=OR(REGEXTEST(B3,"A"),REGEXTEST(B3,"B"))

 OR関数により、2つのREGEXTEST関数の結果のいずれかがTRUEである場合にTRUEに、そうでない場合はFALSEが返されます。
 これもわかりやすいものの対象範囲を「B3:B7」のように拡張しても1つの値しか得られない(いずれかのセルがAまたはBを含む場合にTRUE、そうでない場合にFALSEを返す)のでFILTER関数の条件指定には使えません



 2つ目は「+」演算を使う方法です。
 B列の文字列が「A」か「B」のいずれかを含むかどうかを判定しています。

 C3セル

=REGEXTEST(B3,"A")+REGEXTEST(B3,"B")>0

 それぞれのREGEXTEST関数の結果について、TRUEを1とみなしFALSEを0とみなす足し算が行われます。
 両方のREGEXTEST関数の結果がTRUEの場合(つまり「A」と「B」の両方を含むとき)は足し算の結果は2に、一方のみがTRUEの場合は1になるのでこれらの場合(つまり1つ以上の条件を満たす場合)は「>0」を含めた式全体の結果はTRUEになります。一方で両方FALSEの場合は足し算の結果は0となるので式全体の結果はFALSEとなります。
 対象範囲を「B3:B7」のように拡張したときに各セルを判定した配列が得られるのでFILTER関数の条件指定に使えます。このとき「>0」は省略できます(0以外の数値がTRUE、0がFALSEとみなされるため)。



 3つ目は正規表現で指定する方法です。
 ここでもB列の文字列が「A」か「B」のいずれかを含むかどうかを判定しています。

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

=REGEXTEST(B3,"[AB]")

 正規表現を使ったAND条件は面倒でしたが、OR条件は案外簡単です。
 [ ]の中に条件となる文字を列記すれば、いずれかを含むというOR条件になります。3つ以上の文字も指定できます。
 これもFILTER関数の条件指定に使えます(以降の例も同様)。



 次の画像では半角英大文字のいずれかを含むかどうかを判定しています。

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

=REGEXTEST(B3,"[A-Z]")

 上記例でも出現していますが、このようにして文字の範囲を指定するのもOR条件の一例です。
 大・小文字と全・半角は原則として区別されますが第3引数を「1」とすることで大・小文字を区別しないようにできます。



 最後に、条件とする文字が2文字以上の文字列の場合は次のようにします。

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

=REGEXTEST(B3,"AB|BA")

 複数の文字列を「|」で区切って指定します。さらに区切りを挿むことで3つ以上の文字列も指定できます。

備考

 正規表現の特性上、「TRUE」と判定したくない文字列までも「TRUE」になってしまうのを防ぐのがなかなか難しいです。
 次の画像では、B3セルの文字列内に並ぶ「★」が2個から4個までかどうかを判定するつもりで数式を入力していますが結果はTRUEとなり、意図しない結果となっています。

 C3セル

=REGEXTEST(B3,"★{2,4}")

 「{2,4}」は直前の文字(★)が2つから4つまで並んでいるという意味(3つあれば3つに、4つあれば4つに、というようになるべく長くマッチします)ですが、そもそも部分一致で判定されるため★が5つ並んでいる中の最初の4つにマッチします。「=REGEXTEST(B3,"★★|★★★|★★★★")」としても式の結果は同じです(ただしマッチする部分が異なります)。
 このような判定を見逃しやすいので、条件を設定するにあたってはさまざまな文字列を対象としてテストしてみることも重要です。REGEXEXTRACT関数を使って実際にどの部分がマッチしているのか確認してみるのもよいでしょう。