Parsing an input string for keywords followed by content

I am trying to parse some introductory lines, but I am trying my best to see a solution. However, it should be a well-known template - this is just one that I don't come across often.

Background: I have a short list of string keywords ("HEAD", "GET", "POST", "PUT"), followed by additional string data. In any order there can be a multiple sequence ("KEYWORD blah blah blah KEYWORD blah blah blah"). There are no end characters or end keywords, because XML would have either a new keyword event or end of input. Example:

    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}

The result that I would like to achieve:

    results: [
        "HEAD" ["stuff here"] 
        "GET"  ["more stuff here" "even more stuff here"] 
        "POST" ["other stuff here" "random stuff"] 
        "PUT"  ["still more stuff here"]
    ]

My unsuccessful attempt:

    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" - ; , , - .

.

+4
3

...

;; 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"]]
+2

, , 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 |
       ] 
    ]
]
+2

Here is another option.

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

Again, not ideal in terms of elegance and a similar approach.

+1
source

All Articles