BigQuery での文字列を正規化する方法のメモ。
ここでは以下の文字列の正規化を行います。
- 全角英数記号⇒半角、半角カナ⇒全角など
- 英大文字⇒子文字
- 制御文字(改行、タブ等)を半角空白に
- 連続する空白文字を1文字に
- 先頭、末尾の空白文字の削除
全角英数記号⇒半角、半角カナ⇒全角など
normalize(string, "NFKC") で正規化を行います。
実行例
select normalize("ABC012!#$カナ", NFKC); ABC012!#$カナ
英大文字⇒小文字
lower(string) で英大文字を小文字に変換します。
実行例
select lower("ABCABC"); abcabc
制御文字(改行、タブ等)を半角空白に
正規表現で制御文字を半角空白に置換します。
select regexp_replace('a\n\r\tb', r'[\x00-\x1f\x7f]', ' '); a b
to_code_points(string) で各文字をコードポイントに変換し、 code_points_to_bytes(code_points) でさらにバイトに変換し、 to_hex(bytes) で16進数に変換してみます。
select to_hex(code_points_to_bytes(to_code_points( regexp_replace('a\n\r\tb', r'[\x00-\x19\x7f]', ' ') ))); 6120202062
61:'a'、20:' '、62:'b' のため、改行やタブを半角空白に変換できていることがわかります。
連続する空白文字を1文字に
正規表現で連続する空白文字を1文字に変換します。
select regexp_replace('a b c d e', r'[ ]{2,}', ' '); a b c d e
先頭、末尾の空白文字の削除
先頭、末尾の不要な空白文字列を正規表現で削除します。
select regexp_replace(' a b c ', r'(?:^[ ]+|[ ]+$)', ''); a b c
上記をまとめた正規化関数
create or replace function dataset.normalize_string(str string) as ( regexp_replace( regexp_replace( regexp_replace( lower( normalize(str, NFKC) ) , r'[\x00-\x1f\x7f]', ' ' ) , r'[ ]{2,}', ' ' ) , r'(?:^[ ]+|[ ]+$)', '' ) ); select dataset.normalize_string(' ABC カナ #! '); abc カナ #!