Regex 为什么nextgroup不匹配没有尾随空格的换行符?

Regex 为什么nextgroup不匹配没有尾随空格的换行符?,regex,syntax,syntax-highlighting,vim,Regex,Syntax,Syntax Highlighting,Vim,考虑以下3组突出显示组和语法匹配: hi-Foo-ctermfg=black-ctermbg=red-guifg=black-guibg=red hi Filler ctermfg=黑色ctermbg=绿色GUI FG=黑色GUI BG=绿色 hi Bar ctermfg=黑色ctermbg=蓝色GUI FG=黑色GUI BG=蓝色 syn match Foo“Foo”nextgroup=Filler syn match Filler“\\u s*”nextgroup=包含条 包含同步匹配栏“B

考虑以下3组突出显示组和语法匹配:

hi-Foo-ctermfg=black-ctermbg=red-guifg=black-guibg=red
hi Filler ctermfg=黑色ctermbg=绿色GUI FG=黑色GUI BG=绿色
hi Bar ctermfg=黑色ctermbg=蓝色GUI FG=黑色GUI BG=蓝色
syn match Foo“Foo”nextgroup=Filler
syn match Filler“\\u s*”nextgroup=包含条
包含同步匹配栏“Bar”
hi Baz ctermfg=黑色ctermbg=青色guifg=黑色guibg=青色
hi Qux ctermfg=黑色ctermbg=黄色GUI FG=黑色GUI BG=黄色
syn match Baz“Baz\\u s*”nextgroup=Qux
同步匹配包含的Qux“Qux”
hi Abc ctermfg=黑色ctermbg=洋红色guifg=黑色guibg=洋红色
hi Xyz ctermfg=黑色ctermbg=白色GUI FG=黑色GUI BG=白色
同步匹配Abc“Abc”nextgroup=Xyz skipwhite skipnl
包含的同步匹配Xyz“Xyz”
Filler
Bar
仅在
Foo
之后匹配;类似地,
Qux
仅在
Baz
之后,而
Xyz
仅在
Abc
之后。以下示例与
:为清晰起见,设置列表
,说明
Filler
Bar
Foo
之后如何不匹配,除非
Foo
后面有空格:

Baz
Qux
示例验证了
\\u s
是否匹配换行符,那么当
Baz
被拆分为
Foo
Filler
时,为什么这不起作用呢?此引用与以下内容相关:

当“skipnl”出现时,可以在下一页中找到与nextgroup的匹配项 线路。仅当当前项在当前项末尾结束时才会发生此情况 排队!当“skipnl”不存在时,只有在 同一行中的当前项


Abc
Xyz
示例使用
skipwhite
skipnl
和不使用
\\u s
在这两种情况下确实匹配。这是否意味着
EOL
不符合“在同一行中的当前项目之后”的条件?当然不可能是下一行的一部分?这似乎与以下事实相矛盾:对
\\u s
\n
的正常搜索会导致
EOL
字符在同一行上匹配。

如果匹配在
\n
之前立即结束,则将忽略
下一个组
参数,除非还指定了
skipnl
,即使
nextgroup
中的一个组以
\n
开头匹配

在给定的示例中,由于第一个
Foo
匹配在
\n
之前结束,并且
Foo
没有指定
skipnl
,因此Vim甚至不会尝试匹配
填充
。其他空白的引入允许
Filler
在第二次
Foo
匹配后进行匹配,并且由于
Filler
包括
\n
条也可以匹配,而无需
Filler
指定
skipnl

相关代码位于
src/syntax.c
中:

/* nextgroup ends at end of line, unless "skipnl" or "skipempty" present */
if (current_next_list != NULL
        && syn_getcurline()[current_col + 1] == NUL
        && !(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY)))
    current_next_list = NULL;


我不太清楚你问什么。屏幕截图中的结果似乎与您想要做的匹配(我从代码中了解到)。我不明白为什么第2行的
Filler
EOL
不匹配,这会导致
Bar
与第3行匹配。
/* handle next_list, unless at end of line and no "skipnl" or
 * "skipempty" */
current_next_list = cur_si->si_next_list;
current_next_flags = cur_si->si_flags;
if (!(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY))
        && syn_getcurline()[current_col] == NUL)
    current_next_list = NULL;