Vim Regex соответствует вхождению X, если Y не существует между X и Z - PullRequest
0 голосов
/ 29 ноября 2018

Предположим, у меня есть вхождение

GET.CUSTOMER: 

и вхождение

GET.ACCOUNT:

Как сформулировать выражение Regex, если я хочу, чтобы указанное вхождение совпадало только и только при наличиислово

RETURN

в промежутке между

 GET.CUSTOMER:
        BLOCK OF CODE

и

 GET.ACCOUNT:
        ANOTHER BLOCK OF CODE

не встречается. Предположим, что двоеточие с привязкой разрешено только в функцииname, поэтому не должно быть двоеточий, «прилипших» к слову, отличному от имени функции.Т.е.

RANDOM.FUNCTION:

Разрешено, но

RANDOM.LINE.OF.CODE : MORE.CODE

Не разрешено, за исключением строки в кавычках и апострофах.

Это совпадение будет использоваться в Vimфайл синтаксиса, а не в реальном коде.

@ РЕДАКТИРОВАТЬ Вопрос: возможно ли вышеупомянутое даже?Какие выражения регулярных выражений я должен изучить, что может помочь мне решить эту проблему?

1 Ответ

0 голосов
/ 30 ноября 2018

Следующее будет соответствовать 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.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...