構造化されたテキストファイル
構造化
単純なテキストファイルの場合、構造は行という1段階かもしれない。
様々な方法がある
●セパレータ、区切り子、タブ('\t'),かんま(','),縦棒('|')
などで区切る、CSV形式
●タグを'<'と'>'で囲む、XMLやHTMLがこれに当る
●記号を駆使するもの、JSONがそうだ
●インデント。YAMLがこれに当る
それぞれに、pythonモジュールが提供されている
●記号を駆使するもの、JSONがそうだ
●インデント、たとへば、YAMLがこれに当る(諸説あるが、
"YAMI,Ain`MarkupLanguage"と意味だとされる
●その他、プログラムの設定ファイルなど
CSV
csvファイルは、一度に一行ずつ読み込み、各行を区切り子の
カンマでフィールドに分割し、結果をリストや辞書などの
データ構造に追加するという方法で手作業で処理することも
できるが、標準のcsvモジュールを使った方が良い。csvファイル
の構文解析は、次のような問題があるため、普通に想像するより
かなり複雑だからです。
◉一部のファイルは、カンマ以外に代替の区切り子を持っている。
'|','\t'などが一般的だ
◉一部のファイルはエスケープシーケンスを使っている。区切り子
の文字がフイールド内で使われている可能性がある
◉ファイル内の行末を表す文字はまちまちだ。Unixは'\n'を
Microsoftは'\r\n'を、Appleは以前'\r'を使っていたが、今は'\n'
を使っている。
◉第一行に列名が含まれている場合がある
まず、各行に「列のリスト」が含まれているような「行のリスト」
を読み書きする方法は
import csv
villains = [
['Doctor', 'No'],
['Rosa', 'Klebb],
['Mister', 'Big'],
['Auric', 'Goldfinger'],
['Ernst', 'Blofeld'],
]
with open('villains', 'wt') as fout:
csvout = csv.writer(fout)
csvout.writerows(villains)
このコードからは、次のファイルが作られます。
Doctor,No
Rosa,Klebb
Mister, Big
Auric,Goldfinger
Ernst,Blofeld
では、このファイルを読みだして元のデータ構造を作って見よう。
import csv
with open('villains', 'rt') as fin
cin = csv.reader(fin)
villains = [row for row in cin]
print(villains)
[['Doctor', 'No'],['Rosa', 'Klebb],['Mister', 'Big'],['Auric', 'Goldfinger'],
['Ernst', 'Blofeld'],]
reader()関数が作った構造を利用している。reader()はcinオブジエクトのなかにfor
ループで抽出できる行を作ってくれる。
デフォルトのオプションでreader()とwriter()を使うと、列はカンマで、行は'\n'
で分割される。
XML
区切り子を使った形式では、行と列の2次元までの構造しか作れない。
プログラム間でデータ構造を交換したいのなら階層構造、シーケンス、集合、
その他の構造をテキストでエンコードする方法は必要だ。
XMLは、この条件を満たせるもっとも傑出したマークアップ形式である。
タグを使って区切る
○タグは<文字から始まる。このサンプルXMLのタグは
menu, breakfast, lunch, dinner, itemである
○空白は無視される
○通常、
終了タグで締めくくる
○タグは他のタグのなかで何段階にもネストできる
○開始タグには、オプションの属性を組み込める、
○タグは値を持つことができる。
○thingという名前のタグが値も子も持たない場合、開始タグと終了タグのように
使わなくても、タグを閉じる,>の直前にスラッシュ(/)を入れるて ○データーをどこに入れるかに特別な規則はない
XMLは、データフィールドやメッセージとして使われることが多い
金融のように、専用のXMLフォーマットを多数抱えている業界もある
もっとも簡単に読み取るためには、ElementTreeを使えばいい
次の例は、menu.xmlを構文解析して一部のタグ、属性を表示するプログラム
Import xml.etree.ElementTree as et
tree = et.ElementTree(file='menu.xml')
root = tree.getroot()
root.tag
'menu'
for child in root
print('tag:', child.tag, 'attributes:', child.attrib)
for grandchild in child:
print('\ttag:', grandchild.tag, 'attributes', grandchild.attrib)
len(root)
3
len(root[0])
2
HTML
ウエブの基本的ドキュメント形式である。問題は、その多くが、HTMLの規則に厳密に従って
いないこと。その構文解析が難しい。