いまさら聞けないExcelの使い方講座

【Excel】正規表現って何? Copilotが「[0-9]」や「¥.」などを多用した式を使ってきた

正規表現で使われる基本的な記号を覚えておこう

AIが作った数式、結果は合っているけれど意味がわからない

 Excelで意図する結果を得るための数式が思いつかずに、Copilotに頼むことも多いでしょう。目的の結果が得られれば、ひとまず解決ですが、提案された数式の意味がまったくわからないまま使うのは少し不安ですよね。

 例えば、以下のような表に入力された商品情報から、容量と入数を取り出したいとします。「天然水 550ml 24本」「洗濯洗剤 詰替 1.8L 6個」「小麦粉 1kg 10袋」のように、容量や入数の位置や文字数は一定ではありません。

「商品」列には、「天然水 550ml 24本」のように、商品名と容量、入数が含まれています。「550」や「24」といった数値を取り出す処理は、Copilotに頼むこともありますよね

 容量や入数の位置や表記が一定でないデータから、目的の数値だけを取り出す数式は複雑になりがちです。特に、REGEXEXTRACT関数やREGEXREPLACE関数を使った数式では、「[0-9]」や「¥.」のような記号が並ぶことがあります。これは「正規表現」と呼ばれる記述方法です。正規表現とは、「数字が続く」「特定の文字以外」といった文字列の特徴やパターンを、一定のルールで表現する方法です。

 今回の例でもCopilotは、REGEXEXTRACT関数とREGEXREPLACE関数を使った数式を提案しています。しかし、正規表現を知らなければ、どのように処理されているのかわかりません。

  • B列(容量):=--REGEXREPLACE(REGEXEXTRACT(LOWER(A2),"[0-9]+(¥.[0-9]+)? *(ml|l|kg|g)"),"[^0-9.]","")
  • C列(入数):=--REGEXREPLACE(REGEXEXTRACT(A2,"[0-9]+ *(本|個|袋)"),"[^0-9]","")

 すべての記号を覚える必要はありませんが、今回は、Copilotが作った数式を例に、正規表現の簡単な読み方を覚えておきましょう。

容量を取り出す正規表現を読む

 まず、B列の容量を取り出す数式に含まれるREGEXEXTRACT関数の2つめの引数に指定された正規表現を見てみましょう。REGEXEXTRACT関数は、指定した文字列から正規表現に基づいて文字列を抽出します。

[0-9]+(¥.[0-9]+)? *(ml|l|kg|g)

 [0-9]は「0~9のいずれか1文字」を表します。続く「+」は「直前の条件を1回以上繰り返す」という意味です。つまり、「[0-9]+」で「1桁以上の数字」を表しています。

 「(¥.[0-9]+)?」は、小数部分を表す記述です。「¥.」がピリオドそのもの、「[0-9]+」が小数点以下の数字を意味します。最後の「?」は「直前のまとまりがあってもなくてもよい」という意味なので、「500」のような整数と「1.8」のような小数の両方に対応できます。

 続く「 *(ml|l|kg|g)」に含まれる「*」は直前の文字や条件を0回以上繰り返す記号です。ここでは直前に半角スペースがあるため、「半角スペースが0個以上」という意味になります。「500 ml」のように、数値と単位の間にスペースがある場合にも一致します。「(ml|l|kg|g)」は「|」でつないだ単位の文字列「ml」「l」「kg」「g」のいずれかを意味します。

 なお、1つめの引数「LOWER(A2)」は、元の文字列を小文字に変換するための処理です。「500mL」のような表記も「500ml」として処理されます。

 ここまでのREGEXEXTRACT関数の処理で、「500ml」や「1.8l」に相当する部分が取り出されます。

「容量」列に入力された数式。REGEXEXTRACT関数の処理で、「500ml」や「1.8l」に相当する部分が取り出せます(①)。外側のREGEXREPLACE関数(②)は、正規表現に基づいて指定した文字列を別の文字列に置き換えます

 REGEXREPLACE関数は、正規表現に基づいて、指定した文字列を別の文字列に置き換えます。1つめの引数はREGEXEXTRACT関数の結果、つまり「500ml」といった文字列になります。2つめの引数には正規表現「[^0-9.]」、3つめの引数には置換後の文字列として「""」を指定しています。

"[^0-9.]",""

 「[]」内の先頭にある「^」は、「[]内に指定した文字以外」という意味です。つまり、「[^0-9.]」は「数字と小数点以外」を表します。その部分を、3つめの引数「""」(空文字列)に置き換えることで、「500ml」から「500」だけを残しています。

 なお、数式の先頭にある「--」は、取り出した文字列を数値として扱うための記述です。詳しい仕組みについては、別の機会に紹介します。

入数も同じように読み解ける

 続いて、C列の入数を取り出す数式の正規表現を見てみましょう。B列の正規表現が読み解ければ、同じルールで記述されていることがわかるでしょう。

[0-9]+ *(本|個|袋)

 「[0-9]+」は「1桁以上の数字」、「 *」は「スペースが0個以上」という指定、「(本|個|袋)」は、「本」「個」「袋」のいずれかです。

 REGEXREPLACE関数の2つめ、3つめの引数「"[^0-9]",""」の処理は、B列と同じです。「[^0-9]」に一致する数字以外の文字を削除し、「24本」なら「24」だけを残します。

「入数」列に入力された数式。REGEXEXTRACT関数の処理で、「24本」や「6個」に相当する部分が取り出せます(③)。外側のREGEXREPLACE関数(④)は、正規表現に基づいて指定した文字列を別の文字列に置き換えます

 正規表現を使えば、「左から何文字目」のように位置を指定するのではなく、数字の後ろに「ml」や「本」といった単位があるといった文字列の特徴を指定して探せます。

「単位」も取り出すには?

 ここまでの流れを踏まえれば、正規表現を使って「単位」を取り出す数式もイメージできるのではないでしょうか。

 「(ml|l|kg|g)」や「(本|個|袋)」という正規表現は、「|」でつないだ文字列のいずれかという意味です。これを応用して、REGEXEXTRACT関数に指定すれば、単位だけを取り出せます。

REGEXEXTRACT関数で単位を取り出した結果。正規表現で指定した単位(⑤)を直接取り出すので、REGEXREPLACE関数を使う必要はありません

 入力した数式は以下の通りです。「天然水 550ml 24本」なら「ml」、「洗濯洗剤 詰替 1.8L 6個」なら、LOWER関数で小文字に変換されて「l」が取り出されます。正規表現で指定した文字列(単位)を直接取り出すので、REGEXREPLACE関数を使う必要はありません。

=REGEXEXTRACT(LOWER(A2),"ml|l|kg|g")

 入数の単位なら、LOWER関数も不要です。

=REGEXEXTRACT(A2,"本|個|袋")

 正規表現には、今回紹介した以外にも多くの記号があります。最初からすべて覚える必要はありませんが、今回紹介した表現が読めれば、数式が何を探しているのかはかなり見えてきます。

  • [0-9]:数字
  • +:1回以上の繰り返し
  • ¥.:ピリオドそのもの
  • *:0回以上の繰り返し
  • ?:あってもなくてもよい
  • :または
  • [^0-9]:数字以外

 Copilotが正規表現を含む数式を提案してきたら、そのまま使うだけでなく、見慣れない部分を分解して意味を確認してみてください。正規表現を一から書けなくても、「何を条件にしているのか」を読めるだけで利用のハードルは下がります。