今回はノンプログラマーのための正規表現の入門編をまとめていきたいと思います。
利用する環境はGASとpython(python3.8)です。このブログでよく使ってる2つの環境を対象に説明していきます。
GASやpythonはやらないから関係ないという人も実は触れる機会があるって知ってました?
実は、みなさん大好きエクセルでも実はコンテンツ検索を行う時にワイルドカードを用いた正規表現の部分利用が可能です。
エクセルでも使えると思えば、汎用的に読んでもらえるのかな?w
VBAでRegExpを利用する方法もあるみたいですが、私はVBA苦手人間なので、今回はVBA環境は割愛しています。
まぁそれはさておき、正規表現についてみていきます。
正規表現とは?
そもそも正規表現とはなんでしょうか?
wikipediaによると以下のように定義されていました。
正規表現(せいきひょうげん、英: regular expression)とは、文字列の集合を一つの文字列で表現する方法の一つである
https://ja.wikipedia.org/wiki/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE
よくわかるようなわからないようなw 足りてるような足りてないような。
個人的には、特定の文字列をメタキャラクタという特定の文字や記号を使って、汎用的な1つの文字列に置き換える表現方法かなと思ってます。
なぜ正規表現が便利なのか?
定義だけ聞いても何が便利なのかわからない人に簡単なサンプルです。
例えば以下のようなユーザの情報に電話番号のカラムがあり、ただ携帯番号と固定電話が混ざっていたとします。ここの中から携帯電話の番号だけ抽出して欲しいと言われたらどうしますか?

正直このケースはデータが20件なので、目視でチェックして確認するよってのもの一つの手です。
ただ、これが100件だったら?1000件だったら?ユーザの多いサービスならゆうに数万件の中から探してって言われたら?
目視は限界がありますよね。
じゃぁプログラミングでやろう、ってなるのですが、ここでパッと思いつくのが、携帯番号だから、条件分岐で抽出することを考えるのですかね。
どんな条件か考えてみましょう。
- ・070~090で始まる数値
- ・4つ目または9つ目が”-“のもの
- ・桁数が11桁のもの(固定電話は10桁、携帯電話は11桁ですよね)
あれっ実は桁数でいけば、正規表現使わなくてもいけちゃいそうですね。まぁでも上の2つを利用する場合、正規表現が便利になります。
抽出条件 | 純粋条件分岐 | 正規表現 |
070~090で始まる数値 | 070 or 080 or 090 | 0[789]0 |
4つ目または9つ目が”-“のもの | if str[3] == “-“ か if str[10] == “-“ | \d{3}- |
だいぶ省略してかけますよね。それに汎用性がある。ということで、便利ってなります。
正規表現の使い方
GASでの使用方法
GASではnew RegExp()でイニシャライズさせる方法と、下記のように直接正規表現を/ *** /(スラッシュ二つ)で囲って正規表現を作成する方法の2通りがあります。
function myFunction() {
let list = [
"090-1111-2222", "0587-11-2222", "0120-03-2457", "070-4444-2222", "080-1111-2222"
];
let regex = /0[789]0-\d{4}-\d{4}/;
//listから抽出
for(let x of list){
if(x.match(regex)){
Logger.log(x);
}
}
}
let regexで正規表現を指定して、for文でlistの要素を一つづつ抽出し、match(regex)で一致するかどうかを検証しています。
pythonでの使用方法
pythonで正規表現を使う方法をみていきます。例題として、リストのデータから正規表現で該当データを取得する方法と、文字列から正規表現で該当データを取得する方法です。
import re
list = [
"090-1111-2222", "0587-11-2222", "0120-03-2457", "070-4444-2222", "080-1111-2222"
]
text = "090-1111-2222, 0587-11-2222, 0120-03-2457, 070-4444-2222, 080-1111-2222"
regex = re.compile(r'0[789]0-\d{4}-\d{4}')
pickup =[]
for item in list:
if regex.match(item):
pickup.append(*regex.findall(item))
print("listからpickup:",pickup)
pickup2 = regex.findall(text)
print("文字列からpickup:", pickup2)
基本的な正規表現
基本的な正規表現のパターンをメジャーなものに限りですがピックアップして紹介していきます。軽く辞書っぽくなりますが、ご容赦ください。
文字 | 概要 | 正規表現のサンプル | マッチする文字列の例 |
. | 任意の1文字 にマッチ | . | A あ 1 |
+ | 直前の文字が 1回以上 繰り返す場合にマッチ 最長一致(条件に合う最長の部分に一致) | Ap+le | Aple Apple Appple Apppple |
* | 直前の文字が 0回以上 繰り返す場合にマッチ 最長一致(条件に合う最長の部分に一致) | Ap*le | Ale Aple Apple Appple |
? | 直前の文字が 0個か1個 の場合にマッチ 最長一致(条件に合う最長の部分に一致) | Ap?le | Ale Aple |
+? | 直前の文字が 1回以上 繰り返す場合にマッチ 最短一致(条件に合う最短の部分に一致) | Ap+?le | Aple Apple Appple Apppple |
*? | 直前の文字が 0回以上 繰り返す場合にマッチ 最短一致(条件に合う最短の部分に一致) | Ap*?le | Ale Aple Apple Appple |
| | OR条件 | App(le | el) | Apple Appel |
[…] | 角カッコに含まれるいずれか1文字 | 0[7,8,9]0 0[7-9]0 | 070, 080, 090 |
[^…] | 角カッコに含まれる文字以外にマッチ | 0[^0-6]0 | 070, 080 ,090, 0a0, 0b0… 0-6以外の文字 |
{n} | 直前の文字の桁数を指定 | 1{3} a{3} | 111 aaa |
{n, } | 直前の文字の最小桁数のみ指定 | 1{3, } a{3, } | 111 1111 11111…. aaa aaaa aaaaa…. |
{n, m} | 直前の文字の最小桁数と最大桁数を指定 最長一致(条件に合う最長の部分に一致) | a{3,4} | aaa aaaa |
{n, m}? | 直前の文字の最小桁数と最大桁数を指定 最短一致(条件に合う最長の部分に一致) | a{3,4}? | aaa aaaa |
次に正規表現で予め定義されている正規表現を紹介します。数字・文字・タブ・改行などについて、正規表現で予め定義されているものがあります。
文字 | 概要 | 正規表現のサンプル | マッチする文字列の例 |
\t | タブ | \t | タブがある場合 |
\r | 改行 CR(Carriage Return) | \r | CR改行 |
\n | 改行 LF(Line Feed) | \n | LF改行 |
\d | すべての数字 [0-9]と同じ意味 | \d{3} | 000 ~ 999 |
\D | すべての数字以外の文字 [^0-9]と同じ意味 | \D{3} | aaa あああ etc |
\w | アルファベット、アンダーバー、数字 [a-zA-Z_0-9]と同じ意味 | ^https?://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$ | urlの場合 (http, httpsの両方) |
\W | アルファベット、アンダーバー、数字以外の文字 [^a-zA-Z_0-9]と同じ意味 | \W | |
\s | 空白文字。半角スペース、タブ、改行文字のいずれか 全角スペースは対象外 | \s |
多用する正規表現
頻繁に利用する正規表現は毎回考えるのがめんどくさいので、一覧として持っておくと良いと思います。
対象 | 正規表現 |
メールアドレス | ^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$ |
URL(httpの場合も含む) | ^https?://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$ |
ドメイン | ^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z-]{2,}$ |
携帯電話番号 | ^0[789]0-\d{4}-\d{4}$ |
固定電話番号 | ^0\d(-\d{4}|\d-\d{3}|\d\d-\d\d|\d{3}-\d)-\d{4}$ |
日付(YYYY-MM-DD) | ^\d{4}-\d{2}-\d{2}$ |
郵便番号 | ^\d{3}-\d{4}$ |
まとめ
正規表現について見てきました。
正規表現はこれだけで何かができるというわけではないのですが、プログラミングにおける基礎の部分(土台というニュアンスで)だと思っています。
算数で四則演算をみんながマスターして日常生活が楽になるように、プログラミングにおいて正規表現ができるようになるといろんな局面で役にたつなと。
パターンが多く、全てを説明していませんが、正規表現に関する本もありますし、ブログにも多く紹介されていたりもしますので、是非習得してもらえればと思います。