#個人情報をマスキングする
ダッシュボードでデータを掲載したいものの、個人情報は情報セキュリティ的に載せられない。
CRM(顧客情報管理システム)などで手入力されるデータは表記が揺れるため、
SQLやPowerQueryには限界を感じ、自分の扱う個人情報で特に多い電話番号のマスキングに
正規表現を使用してみた。
SQLでもある程度できるが、使用しているDBで一般的なreplace関数の引数が使えず、
何度も電話番号が出現した場合は対応できないため、諦めた。
#テストデータを用意する
携帯電話と固定電話を含んだリストを作成する。
メモなどに入力され、電話番号以外にも情報があり、それは残したい想定。
data = {'ID':[1, 2, 3, 4, 5],
'Memo':['2021/12/12_テスト000-0123-4567テスト',
'2021/12/12_テスト(000)0123-4567テスト',
'2021/12/12_テスト00001234567テスト',
'2021/12/12_テスト(00)0123-4567テスト',
'2021/12/12_テスト(000-123-4567テスト']
}
df = pd.DataFrame(data)
#どの正規表現がいいか試す
##ハイフンや()を取り除いて10桁の数字を指定してみる
ハイフンや()を取り除くために、英数字以外を空白に置き換えて、
10桁の数字の場合、「***」に置き換えしてみた。
英数字以外は__\W__や__[^a-zA-Z0-9]__で表現されるらしい。
結果は以下で、電話番号自体はマスクされた。
df['masked'] = df['Memo'].map(lambda _: re.sub(r'\d{10}', r'***', re.sub(r'\W', r'', str(_))))
#out put
# ID Memo masked
#0 1 2021/12/12_テスト000-0123-4567テスト 20211212_テスト***7テスト
#1 2 2021/12/12_テスト(000)0123-4567テスト 20211212_テスト***7テスト
#2 3 2021/12/12_テスト00001234567テスト 20211212_テスト***7テスト
#3 4 2021/12/12_テスト(00)0123-4567テスト 20211212_テスト***テスト
#4 5 2021/12/12_テスト(000-123-4567テスト 20211212_テスト***テスト
しかし、日付の記号も消えるという、やや残念な様子である。
##3桁-4桁-3桁の正規表現を指定してみる
正確には、
『0-1文字の数字以外+2-3桁の数字+0-1文字の数字以外
+3-4桁の数字+0-1文字の数字以外+4桁』の数字を指定してみた。
0~9の数字は__\d__か__[0-9]__で表現される。
__{}__は、直前のものの繰り返し回数を指定できる。
\d{3}は3桁、\d{2,3}は2~3桁の、0~9の数字のどれがということになる。
__?は0-1回という意味で、[^0-9]か\D__は数字以外ということで、
__^を付けるとそれ以外という意味になる。(^__だけは、文字列の先頭)
__[^0-9]?__とすることで、0-1回の数字以外が入るという意味になる。
結果は以下で、日付は残り、電話番号自体もマスクされた。
df['masked'] = df['Memo'].map(lambda _: re.sub(r'\D?\d{2,3}\D?\d{3,4}\D?\d{4}', r'***', str(_)))
#out put
# ID Memo masked
#0 1 2021/12/12_テスト000-0123-4567テスト 2021/12/12_テスト***テスト
#1 2 2021/12/12_テスト(000)0123-4567テスト 2021/12/12_テスト***テスト
#2 3 2021/12/12_テスト00001234567テスト 2021/12/12_テスト***テスト
#3 4 2021/12/12_テスト(00)0123-4567テスト 2021/12/12_テスト***テスト
#4 5 2021/12/12_テスト(000-123-4567テスト 2021/12/12_テスト***テスト
#結果
この正規表現に当てはまる電話番号以外データがない限り、
基本的には上記でカバーできそうだった。
正規表現は情報を流し読みするだけでは理解できず、
実際にいろいろ試してみて勉強になった。
正規表現について詳しくは、書籍や他記事を参照してほしい。