如何使用`parse`来获取所有使用Red语言的所有搜索字符串的行

时间:2017-09-25 16:45:07

标签: parsing rebol red

我试图从包含搜索字符串列表中所有字符串的行列表中提取。我正在尝试使用and关键字(如http://rebol.com/r3/docs/concepts/parsing-summary.html中所述)来跟踪代码,以仅包含具有srchstr块的所有字符串的那些行:

lines: [ 
    "this is first (1st) line"
    "second line"
    "third line"
    "this is second sentence"
    "first line or sentence"
    "third sentence"    ]

srchstr: ["line" "first"]

probe parse lines [and reduce srchstr]
probe parse lines [and srchstr]  

没有错误消息,但输出仅为:

false
false

我也尝试过:

foreach line lines 
    [parse line [and srchstr]
        (print line)]

但这会打印所有线条。

所需的输出是:

    [ 
    "this is first (1st) line"
    "first line or sentence"
    ]

从这些代码中可以明显看出我对此非常陌生,尽管我试图阅读它。

问题出在哪里?如何获得所需的输出?

2 个答案:

答案 0 :(得分:2)

这不是解析的典型任务,但是用foreach更好地解决.. .. [all [..]]

>> foreach line lines [all [find line srchstr/1 find line srchstr/2 print line]]
this is first (1st) line
first line or sentence

具有从多个搜索字符串动态组合的条件的变体

foreach line lines compose/only  [ 
    all   (
        collect [ 
            foreach str srchstr [
                keep compose [find line (str)] 
            ] 
            keep [print line]
        ]  
    ) 
]

好的,搜索块中有多个字符串的原始解析解决方案

>> rule:  [collect some into [   keep to end | to end ] ]
== [collect some into [keep to end | to end]]
>> foreach str srchstr [ insert  rule/4  compose [ahead to (str)] ] 
== [ahead to "line" keep to end | to end]
>> parse lines rule
== ["this is first (1st) line" "first line or sentence"]

答案 1 :(得分:1)

要匹配整个单词,两个版本都会使用parse预先传递来提取所说的单词:

extract-words: func [series [string!]][
    letters: charset [#"0" - #"9" #"a" - #"z"]
    series: parse series [collect any [keep some letters | skip]]
]

使用FIND

这会产生一系列find结果,并确认符合all

contains-all: func [series [string!] words [block!] /local word][
    series: extract-words series

    all collect [
        foreach word words [
            keep find series word 
        ]
        keep true
    ]
]

然后你可以遍历你的字符串来找到匹配项:

collect [
    foreach line [ 
        "this is first (1st) line"
        "second line"
        "third line"
        "this is second sentence"
        "first line or sentence"
        "third sentence"
    ][
        if contains-all line ["line" "first"][keep line]
    ]
]

使用PARSE

此版本会创建一个与parse字词匹配的sort规则:

contains-all: function [series [string!] words [block!]][
    parse sort extract-words series collect [
        foreach word sort copy words [
            keep 'thru
            keep word
        ]
        keep [to end]
    ]
]