[正規表現] CSV形式データからフィールドの値を抽出する。 | Archive Redo Blog

Archive Redo Blog

DBエンジニアのあれこれ備忘録

値の中に','、'"'などを含むCSV形式データから各フィールドの値を抽出するのは意外と面倒なものですが、正規表現を使えば比較的簡単に実現可能です。


【書式1】
 (?:^|,)(?:"((?:[^"]|"")*)"|([^,"]*))
行の先頭から「区切り文字+値」の形でマッチングし、各フィールドの値を抽出します。
※ただし、行頭に空のフィールドがある場合、スキップされてしまいます。
【書式2】
(?:"((?:[^"]|"")*)"|([^,"]*))(?:$|,)
行の先頭から「値+区切り文字」の形でマッチングし、各フィールドの値を抽出します。
※ただし、行末に余分なフィールドがヒットしてしまいます。
どちら書式も、'()'内の正規表現にマッチした文字列を後方参照することによって各フィールドの値を抽出します。

'()'はたくさんありますが、'?:'がついた'()'はグループ化だけを行うもので後方参照できません。

後方参照できる'()'は2つあり、1つは'"'で括られた値にマッチし、もう1つは'"'で括られていない値にマッチします。
※いずれも区切り文字は含まれません。

ただし、各書式とも赤字で示した通り、行頭、行末の処理に若干問題がありますので、これらはプログラミングによってうまく処理してやらなければなりません。

値の中に改行が含まれるデータや、不正な形式のデータの扱いなどについても同様です。

そのあたりが若干面倒ではありますが、値を抽出するという部分だけでも正規表現で実現できると随分と楽になります。

ちなみに、TSV(タブ区切り)形式データに関しても同じ要領で正規表現を使うことができます。

【書式1】
(?:^|\t)(?:"((?:[^"]|"")*)"|([^\t"]*))
【書式2】
(?:"((?:[^"]|"")*)"|([^\t"]*))(?:$|\t)