Следующее будет соответствовать GET.CUSTOMER:
, если за ним следует GET.ACCOUNT:
, но между ними нет RETURN
.Возможно, вам придется немного подправить это;Я оставил здесь наши утверждения о границе ключевых слов и другой пух.Кроме того, поскольку это многострочное совпадение, оно может быть медленным или прерываться, если между ними слишком много строк.
syntax match getCustomerBlockWithoutReturn
\ "\%#=1\%(GET\.CUSTOMER:\_.\{-}\%(RETURN\|GET\.ACCOUNT:\)\)\@>\%(GET\.ACCOUNT:\)\@<="
\ contains=getCustomer
syntax match getCustomer "GET\.CUSTOMER:" contained
hi link getCustomer Statement
Первый getCustomerBlockWithoutReturn
соответствует всему блоку.getCustomer
содержится в первом (contained
предотвращает сопоставление вне его) и выполняет выделение через группу :highlight
.Это потому, что вы хотите выделить только слово, начинающее блок, а не весь блок.
Основная проблема с этим регулярным выражением состоит в том, что обычно backtracking очень трудно найтисовпадение, и было бы пропущено GET.ACCOUNT:
... GET.CUSTOMER:
частей только для того, чтобы найти RETURN
и сделать совпадение, даже если оно охватывает несколько фактических блоков.
Используя (неясный) весь шаблон multi (:help /\@>
), мы предотвращаем возврат и сопоставляем минимальную (через \{-}
) область (включая переводы строки, используя \_.
вместо .
) от GET.CUSTOMER:
до RETURN
или GET.ACCOUNT:
. положительный взгляд за (через /\@<=
) затем утверждает, что этот конец на самом деле равен GET.ACCOUNT:
, то есть у нас есть блок без RETURN
.(Примечание: по крайней мере в моей версии Vim 8.1.536 мне пришлось принудительно использовать более старый механизм регулярных выражений через \%#=1
; я сообщил об этой ошибке разработчикам Vim.)