Vim 正则表达式:两个正则表达式冲突

Vim Regex: Two regexes conflicting

在尝试为内部语言编写语法文件时,我试图捕获前面有 / 和将它分配给一个 hi def link 和每行的 第二个 单词(由 // 括起来)并将它分配给第二个 hi def link.

对于语法:

cmo/create/mo1///tri
createpts/brick/xyz/2,2,2/0.,0.,0./1.,1.,1./1,1,1

我正在尝试将 cmocreatepts 捕获为 argOne,将 createbrick 捕获为 argTwo:

syn match argOne '^\zs[^\/]\+\ze\/'
syn match argTwo '^[^\/]\+\/\zs[^\/]\+\ze\/'

hi def link argOne         Type
hi def link argTwo         Statement

问题是它们冲突:当两个 sys match 语句都存在时,ViM 只捕获 argOne 找到的那些。但是孤立地,当两个 syn match 之一被注释掉时, argOneargTwo 都可以完美地工作。

我怎样才能使这两个语句相互配合?

一个解决方案是创建包含的匹配项,定义匹配前两个参数的 argOneTwo,然后为第一个和第二个匹配项提供匹配项:

syn match argOne '^\zs[^\/]\+\ze' contained
syn match argTwo '\/\zs[^\/]\+\ze\/' contained
syn match argOneTwo '^\zs[^\/]\+\/[^\/]\+\ze\/' contains=argOne,argTwo

hi def link argTwo         Statement
hi def link argOne         Type

您可以使用 nextgroup=... 构建一系列匹配的语法组。这比@herbert 定义包含各个语法组的父组的解决方案更好。

syntax match argOne "^[^/\]\+" nextgroup=sepOne
syntax match sepOne "/" contained nextgroup=argTwo
syntax match argTwo "[^/\]\+" contained

请注意 sepOneargTwo 具有 contained 属性,因此它们仅在通过 nextgroup=... 指示时匹配。如果没有它,它们将在更多位置匹配。