Как использовать `parse`, чтобы получить все строки со всеми строками поиска на красном языке

Я пытаюсь извлечь из списка строк, которые имеют все строки из списка строк поиска. Я пытаюсь следующий код с помощью 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 ответа

Решение

Чтобы соответствовать целым словам, обе версии будут использовать 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

Эта версия создает 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]
    ]
]

Это не типичная задача для разбора, но лучше решаемая с помощью foreach .. ..[все [..]]

>> 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"]
Другие вопросы по тегам