Как использовать `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"]