2017年5月1日月曜日

実際にパターンファイルを作ってみて、シンプルなテキスト抽出に挑戦しよう。

下のようなシンプルなテキストがあったとします。
一人分の情報、名前と住所が、3人分書かれているテキストです。
名前:佐藤
住所:東京都
=====
名前:田中
住所:大阪府
=====
名前:鈴木
住所:愛知県
これを表にまとめて、下のようなcsv形式のファイルを出力することを目標とします。1行に一人分の名前と住所を出力します。
佐藤,東京都
田中,大阪府
鈴木,愛知県

パターンを書いてみよう

まずはテキストを分析


それでは、もとのテキストを、エディタで詳しく見てみましょう。



一人分の情報は、
名前と住所が2行で書かれています。
この名前と住所が出現する箇所を、パターンとして記述します。

それでは、構造をもう少し詳細に分析します。

1行目を見てみましょう。
"名前:"という文字列、その直後に抽出すべき”佐藤”があります。
その後に改行。
2行目を見てみましょう。
"住所:"という文字列、その直後に抽出すべき”東京都”があります。
ここまでが、一人分のパターンです。

抽出パターンを書く


まずは、これらをそのまま羅列します。
"名前:" word eol "住所:" word
これら一つ一つを”単パターン”と呼ぶことにしましょう。
それぞれの意味はどういうものなのでしょうか?

”名前:” ”住所:”
これらは、一人分のパターンに毎回出てくる、決まった文字列ですね。
ダブルクォーテーション(”)で囲った文字列は、そっくりそのままの文字列にマッチします。

word
wordは、任意の文字列にマッチします。
この例だと、一人目では"佐藤"、"東京都"にマッチします。

eol
これは改行です。End Of Line (行の終わり)の頭文字をとったものです。

これらを、連結しましょう。連結には”>”を使います。
"名前:" > word > eol > "住所:" > word
これで、テキスト通りのパターンが出来上がったことになります。
それでは、さっそくパターンファイルを作成しておきましょう。

コマンドラインで、
moji template ptn.txt
と打って、パターンファイルの雛形を作ってから、
さっきのパターンをコピペしました。
@pattern
main {
  "名前:" > word > eol > "住所:" > word
}
@format
  
@end

出力フォーマットを書く


あとは、出力のフォーマットを書くだけです。
どうすればいいと思いますか?
名前と住所にマッチした、wordの中身を書き出したいですよね。

そのためには、1つ目のwordと、2つ目のwordを区別しなきゃなりません。
そこで、マッチした単パターンには、それぞれラベルを付けておいて、出力時に取り出すことができるようになっています。
wordの後に、'$name'と書くと、出力フォーマットのところに、$nameと書くだけで、
キャプチャされた文字列を出力できます。
それでは、以下のようにパターンを改善しましょう。
@pattern
main {
  "名前:" > word$name > eol > "住所:" > word$pref
}
@format
  
@end
名前は'$name'として、住所は'$pref'としてキャプチャできました。
これを、出力フォーマットに指定しましょう。
@pattern
main {
  "名前:" > word$name > eol > "住所:" > word$pref
}
@format
  $name,$pref
@end
$nameと$prefをカンマ(,)で区切りました。

ついに実行


それでは、実際に抽出してみましょう。
抽出対象のテキストファイルは、"text.txt"という名前で保存しておきました。
moji -itext.txt -pptn1.txt -otable.csv
出力された"table.csv"をエディタで開くと、下のようになっているはずです。


もちろんcsv形式ですので、エクセルで開くこともできます。

好きな文字列を出力


最後に、ちょっと遊んで見ましょう。
表形式ではなく、文章として出力します。出力フォーマットを以下のように変更してください。
@format
  $name"さんは"$pref"に住んでいます。"
@end
-oオプションを無しにして、出力先を指定せずに実行すると、
moji -itext.txt -pptn1.txt



このように、文章としても出力することができます。

出力フォーマットに、"好きな文字列"のように、ダブルクォーテーションで文字列を囲んで記述すれば、そのまま文字列が出力されるのです。

まとめ


今回の記事では、フォーマットの基本的な部分を理解していただけたかと思います。


0 件のコメント:

コメントを投稿