Lookahead работает аналогично тому, как это происходит в движке регулярных выражений.
Этот запрос не соответствует, потому что следующая буква должна быть 'u'
, а не 'i'
.
word = 'q' &'u' 'i' 't'
Этот запрос успешно выполняется:
word = 'q' &'u' 'u' 'i' 't'
Этот запрос успешно выполняется:
word = 'q' 'u' 'i' 't'
Что касается вашего примера, попробуйте что-то в этом духе, вам вообще не нужно использовать lookaheads:
expression
= termPair ( _ delimiter _ termPair )*
termPair
= term ('.' term)? ' ' term ('.' term)?
term "term"
= $([a-z0-9]+)
delimiter "delimiter"
= "."
_ "whitespace"
= [ \t\n\r]+
РЕДАКТИРОВАТЬ : добавлен еще один пример для комментариев ниже.
expression
= first:term rest:delimTerm* { return [first].concat(rest); }
delimTerm
= delimiter t:term { return t; }
term "term"
= $((!delimiter [a-z0-9. ])+)
delimiter "delimiter"
= _ "." _
_ "whitespace"
= [ \t\n\r]+
РЕДАКТИРОВАТЬ : добавлено дополнительное объяснение термина выражения.
Я попытаюсь немного разобрать термин «правило» $((!delimiter [a-z0-9. ])+)
.
$()
преобразует все внутри в один текстовый узел, например [].join('')
.
«Один»символ "термина" - это любой символ [a-z0-9. ]
, если бы мы хотели упростить его, мы могли бы вместо этого сказать .
.Перед сопоставлением символа мы хотим посмотреть на delimiter
, если мы найдем delimiter
, мы прекращаем сопоставлять этот символ.Поскольку нам нужно несколько символов, мы делаем все это несколько раз с помощью +
.
. В PEG-парсерах это обычная идиома, чтобы двигаться вперед таким образом.Я узнал идею из документации treetop для сопоставления строки.