ほとんどの解析問題と同様に、私は入力フォーマットの要素を最もよく説明する文法を構築しようとします。
[comma ending value-chars qmark quoted-chars value header row]
いくつかの動詞:
[row-feed emit-value]
そして手術名詞:私は、私はおそらくそれを打破することができたとし
[current chunk current-row width]
は、このケースでは、名詞を持っていますもう少しですが、十分に機能します。まず、基礎:
comma: ","
ending: "^/"
qmark: {"}
value-chars: complement charset reduce [qmark comma ending]
quoted-chars: complement charset reduce [qmark]
今、値の構造。我々はそれらを見つけると引用符で囲まれた値は、有効な文字や引用符の塊から構築されていますdelimiter
は、各行の先頭にending
に設定されていることを
current: chunk: none
quoted-value: [
qmark (current: copy "")
any [
copy chunk some quoted-chars (append current chunk)
|
qmark qmark (append current qmark)
]
qmark
]
value: [
copy current some value-chars
| quoted-value
]
emit-value: [
(
delimiter: comma
append current-row current
)
]
emit-none: [
(
delimiter: comma
append current-row none
)
]
注意し、私たちとすぐに値を渡すようcomma
に変更。したがって、入力行は[ending value any [comma value]]
と定義されます。
すべてのことが残っているが、文書の構造を定義することです:
current-row: none
row-feed: [
(
delimiter: ending
append/only out current-row: copy []
)
]
width: none
header: [
(out: copy [])
row-feed any [
value comma
emit-value
]
value body: ending :body
emit-value
(width: length? current-row)
]
row: [
row-feed width [
delimiter [
value emit-value
| emit-none
]
]
]
if parse/all stream [header some row opt ending][out]
は、すべてのそれらの単語を遮蔽するためにそれをラップし、あなたが持っている:
REBOL [
Title: "CSV Parser"
Date: 19-Nov-2012
Author: "Christopher Ross-Gill"
]
parse-csv: use [
comma ending delimiter value-chars qmark quoted-chars
value quoted-value header row
row-feed emit-value emit-none
out current current-row width
][
comma: ","
ending: "^/"
qmark: {"}
value-chars: complement charset reduce [qmark comma ending]
quoted-chars: complement charset reduce [qmark]
current: none
quoted-value: use [chunk][
[
qmark (current: copy "")
any [
copy chunk some quoted-chars (append current chunk)
|
qmark qmark (append current qmark)
]
qmark
]
]
value: [
copy current some value-chars
| quoted-value
]
current-row: none
row-feed: [
(
delimiter: ending
append/only out current-row: copy []
)
]
emit-value: [
(
delimiter: comma
append current-row current
)
]
emit-none: [
(
delimiter: comma
append current-row none
)
]
width: none
header: [
(out: copy [])
row-feed any [
value comma
emit-value
]
value body: ending :body
emit-value
(width: length? current-row)
]
row: [
opt ending end break
|
row-feed width [
delimiter [
value emit-value
| emit-none
]
]
]
func [stream [string!]][
if parse/all stream [header some row][out]
]
]
私はそれを与えたばかげたデータを扱うように(これまでのところ)回答に驚くほどの応答時間があります! – HostileFork