【问题标题】:Parsing string input for keywords followed by content解析关键字的字符串输入,后跟内容
【发布时间】:2016-03-14 23:52:10
【问题描述】:

我正在尝试解析一些字符串输入,但我很难找到解决方案。不过,这一定是一种众所周知的模式——只是我不经常遇到的一种。

背景:我有一个简短的字符串关键字列表(“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”运算符不是考虑这种模式的正确方法;当我希望它找到任何关键字时,它会跳到该规则块中第一个可用关键字的下一次出现。

任何提示将不胜感激。

【问题讨论】:

    标签: parsing rebol rebol3


    【解决方案1】:

    这个怎么样...

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

    【讨论】:

    • 谢谢——这要归功于 draegtun 和 sqlab——我意识到一个简单的作弊方法是让我在输入中添加我自己的终止符,但我很高兴看到更多的解析——适当的方法。
    【解决方案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 |
           ] 
        ]
    ]
    

    【讨论】:

      【解决方案3】:

      这是另一个变体。

      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
      

      再一次,在优雅和相似的方法方面并不完美。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-01
        • 2022-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多