解析关键字后跟内容的字符串输入
Parsing string input for keywords followed by content
我正在尝试解析一些字符串输入,但我很难找到解决方案。但是,这一定是一种众所周知的模式 -- 只是我不常遇到的一种模式。
背景:我有一个简短的字符串关键字列表("HEAD"、"GET"、"POST"、"PUT"),每个关键字后面都跟有其他字符串数据。可以有多个序列,顺序任意 ("KEYWORD blah blah blah KEYWORD blah blah blah")。没有像 XML 那样的终止符或结束关键字——要么是关键字子句的新出现,要么是输入的结尾。示例:
str: {HEAD stuff here GET more stuff here POST other stuff here GET even more stuff here PUT still more stuff here POST random stuff}
我想要实现的输出:
results: [
"HEAD" ["stuff here"]
"GET" ["more stuff here" "even more stuff here"]
"POST" ["other stuff here" "random stuff"]
"PUT" ["still more stuff here"]
]
我的拙劣尝试是:
results: ["head" [] "get" [] "post" [] "put" []]
rule1: ["HEAD" (r: "head") | "GET" (r: "get") | "POST" (r: "post") | "PUT" (r: "put")]
rule2: [to "HEAD" | to "GET" | to "POST" | to "PUT" | to end]
parse/all str [
some [
start: rule1 rule2 ending:
(offs: offset? start ending
append select results r trim copy/part start offs
) :ending
| skip]
]
我知道规则 2 是个笨蛋——"to" 运算符的使用不是思考这种模式的正确方法;当我希望它找到任何关键字时,它会跳到该规则块中第一个可用关键字的下一次出现。
如有任何提示,我们将不胜感激。
这个怎么样...
;; parse rules
keyword: [{HEAD} | {GET} | {POST} | {PUT}]
content: [not keyword skip]
;; prep results block... ["HEAD" [] "GET" [] "POST" [] "PUT" []]
results: []
forskip keyword 2 [append results reduce [keyword/1 make block! 0]]
parse/case str [
any [
copy k keyword copy c some content (
append results/:k trim c
)
]
]
使用你的 str
然后 results
会得到你想要的....
["HEAD" ["stuff here"] "GET" ["more stuff here" "even more stuff here"] "POST" ["other stuff here" "random stuff"] "PUT" ["still more stuff here"]]
可能不太优雅,但即使使用 Rebol2
results: ["HEAD" [] "GET" [] "POST" [] "PUT" []]
keyword: [{HEAD} | {GET} | {POST} | {PUT}]
parse/case str [
any [
[copy k keyword c1: ] | [skip c2:]
[[keyword | end] (
append results/:k trim copy/part c1 c2
) :c2 |
]
]
]
这是另一种变体。
str: {HEAD stuff here GET more stuff here POST other stuff here GET even more stuff here PUT still more stuff here POST random stuff}
results: ["HEAD" [] "GET" [] "POST" [] "PUT" []]
possible-verbs: [ "HEAD" | "GET" | "POST" | "PUT" | end ]
parse/all str [
some [
to possible-verbs
verb-start: (verb: first split verb-start " ")
possible-verbs
copy text to possible-verbs
(if not none? verb [ append results/:verb trim text ])
]
]
probe results
再次强调,在优雅和方法上并不完美。
我正在尝试解析一些字符串输入,但我很难找到解决方案。但是,这一定是一种众所周知的模式 -- 只是我不常遇到的一种模式。
背景:我有一个简短的字符串关键字列表("HEAD"、"GET"、"POST"、"PUT"),每个关键字后面都跟有其他字符串数据。可以有多个序列,顺序任意 ("KEYWORD blah blah blah KEYWORD blah blah blah")。没有像 XML 那样的终止符或结束关键字——要么是关键字子句的新出现,要么是输入的结尾。示例:
str: {HEAD stuff here GET more stuff here POST other stuff here GET even more stuff here PUT still more stuff here POST random stuff}
我想要实现的输出:
results: [
"HEAD" ["stuff here"]
"GET" ["more stuff here" "even more stuff here"]
"POST" ["other stuff here" "random stuff"]
"PUT" ["still more stuff here"]
]
我的拙劣尝试是:
results: ["head" [] "get" [] "post" [] "put" []]
rule1: ["HEAD" (r: "head") | "GET" (r: "get") | "POST" (r: "post") | "PUT" (r: "put")]
rule2: [to "HEAD" | to "GET" | to "POST" | to "PUT" | to end]
parse/all str [
some [
start: rule1 rule2 ending:
(offs: offset? start ending
append select results r trim copy/part start offs
) :ending
| skip]
]
我知道规则 2 是个笨蛋——"to" 运算符的使用不是思考这种模式的正确方法;当我希望它找到任何关键字时,它会跳到该规则块中第一个可用关键字的下一次出现。
如有任何提示,我们将不胜感激。
这个怎么样...
;; parse rules
keyword: [{HEAD} | {GET} | {POST} | {PUT}]
content: [not keyword skip]
;; prep results block... ["HEAD" [] "GET" [] "POST" [] "PUT" []]
results: []
forskip keyword 2 [append results reduce [keyword/1 make block! 0]]
parse/case str [
any [
copy k keyword copy c some content (
append results/:k trim c
)
]
]
使用你的 str
然后 results
会得到你想要的....
["HEAD" ["stuff here"] "GET" ["more stuff here" "even more stuff here"] "POST" ["other stuff here" "random stuff"] "PUT" ["still more stuff here"]]
可能不太优雅,但即使使用 Rebol2
results: ["HEAD" [] "GET" [] "POST" [] "PUT" []]
keyword: [{HEAD} | {GET} | {POST} | {PUT}]
parse/case str [
any [
[copy k keyword c1: ] | [skip c2:]
[[keyword | end] (
append results/:k trim copy/part c1 c2
) :c2 |
]
]
]
这是另一种变体。
str: {HEAD stuff here GET more stuff here POST other stuff here GET even more stuff here PUT still more stuff here POST random stuff}
results: ["HEAD" [] "GET" [] "POST" [] "PUT" []]
possible-verbs: [ "HEAD" | "GET" | "POST" | "PUT" | end ]
parse/all str [
some [
to possible-verbs
verb-start: (verb: first split verb-start " ")
possible-verbs
copy text to possible-verbs
(if not none? verb [ append results/:verb trim text ])
]
]
probe results
再次强调,在优雅和方法上并不完美。