結論
csvを読み込む時,エンコーディングで'utf-8-sig'
を指定する.
with open(file,encoding='utf-8-sig') as f:
csvreader = csv.reader(f)
csvを読み込んだとき先頭に\ufeff
がある場合も同じ対処でOK.
発端
csvにある項目を一気にgrep
的に検索したかった.
テストで動かしたとき,明らかに一致している文字列があるのに検出してくれなかった.
シェルスクリプトで書く方が楽な人は多いかもね...
aaa
bbb
ccc
aaajfdo
fewapjg
bbbdiaf
from glob import glob
import csv
import re
target_csv = "search_word.csv"
target_path = "./*" #カレントディレクトリ
pattern = re.compile(r'.cpp|.hpp|.py') #検索したいファイルの拡張子
files = [p for p in glob(target_path, recursive=True)if pattern.search(p) and os.path.isfile(p)] #一応ディレクトリ避けをする
with open(target_csv, encoding='utf8') as f:
csvreader = csv.reader(f)
for row in csvreader:
word = row[0]
print("word:",word)
for file in files:
with open(file, encoding='utf8') as ff:
data_list = ff.readlines()
for ind,l in enumerate(data_list):
if word in l:
print(l)
出力としてはaaa
とbbb
でヒットしてくれればいい
word: aaa
word: bbb
bbbdiaf
word: ccc
aaa
がヒットしていない.なぜ?おかしいよ.
結局なんだったか
repr(word)
でどういう状態なのかみてみる
word: aaa
'\ufeffaaa'
word: bbb
'bbb'
word: ccc
'ccc'
aaa
の前に変なのがついてる...
検索してみるとBOM(Byte Order Mark)というやつのユニコード表示らしいです.
web系の人にとっては当然の知識なんですかね.
簡単に言うと、「UTF-8 で文字を書いたよ」と PC に知らせるものです。
引用:ウェブ制作:「UTF-8」の「BOM」って何?付けた方がいいの?
BOMがある場合は'utf-8-sig'
でエンコード,ない場合は'utf8'
でエンコードしてやればいいようです.自動で見分けて読み込む関数作ってる方もいらっしゃいました.
Python Tips: Python で UTF-8 の BOM ありなしを見分けたい
エクセルからCSV UTF-8でエクスポートしたのでBOMがついたのかもしれません.
エクセルのCSVでエクスポートしてやればBOMなしの状態で出てきました.
おわり
#省略
with open(target_csv, encoding='utf-8-sig') as f:
#省略
word: aaa
aaajfdo
word: bbb
bbbdiaf
word: ccc
はい.