2009年1月19日月曜日

JSONとCL (その2)

yasonを使って、jsonを含むテキストチャンクからJSONらしき部分を抽出する処理を書いた。不細工な書きぶりだけどそこそこ動く。

;; 多値でparse結果を返す関数
(defun analyze (string &key (start 0))
(handler-case (values (with-input-from-string (s string :index index :start start)
(json:parse s))
index t)
(condition () (values nil (incf start) nil))))

;; それを使ってそれなりのチャンクを処理する関数
(defun analyze-chunk (chunk)
(let ((result)
(len (length chunk))
(start 0))
(loop
(multiple-value-bind (match new-start match-p)
(analyze chunk :start start)
(when match-p
(push match result))
(when (> new-start len)
(return (nreverse result)))
(setq start new-start)))))

(analyze-chunk "テストデータを作ってみました。\\n\\r{ \"input_01\" : 123, \"input_02\" : \"hoge\" }\\n\\rこんな感じでいいんでしたっけ?")
;; => (#<EQUAL hash-table with 2 entries @ #x10010b53a2>)
(analyze-chunk "abcd{\"hoge\" : 3} ほげほげ 3")
;; => (#<EQUAL hash-table with 1 entry @ #x10010ee552> 3)
(analyze-chunk "abcd{\"hoge\"\" : 3} ほげほげ 3 [3, 8 ,2")
;; => ("hoge" 3 3 3 8 2)
(analyze-chunk "abcd{\"hoge\"\" : 3} ほげほげ 3 [3, 8 ,2]")
;; => ("hoge" 3 3 (3 8 2))
(analyze-chunk "abcd{\"hoge\" : 3} ほげほげ 3 [3, 8 ,2]")
;; => (#<EQUAL hash-table with 1 entry @ #x100117aef2> 3 (3 8 2))

;; これはerrorになる。skip-whitespaceがおかしい?
(json:parse "{ \"input_01\" : 123,\\n\\r \"input_02\" : \"hoge\" }")

yasonのskip-whitespace関係のせいか、JSON構造の中に改行コードがあるとjson:parseがエラーになる。
これは次回探ってみる。

こつこつ。

0 件のコメント: