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

How to use `parse` to get all lines with all search strings in Red language

我正在尝试从包含搜索字符串列表中所有字符串的行列表中提取。我正在尝试使用 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"
    ]

从这些代码中可以明显看出我对此很陌生,尽管我已经尝试阅读它。

问题出在哪里,我怎样才能得到想要的输出?

这不是典型的解析任务,但最好用 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"]

为了匹配整个单词,两个版本都将使用 parse 预传递来提取所述单词:

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

使用查找

这将创建 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 规则,该规则将匹配 sorted 词:

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