正则表达式在查找中有效,但在 .sublime-syntax 文件中无效

Regex expression works in find, but not in .sublime-syntax file

我想突出显示 $( 和 $) 之间的任何内容。在 .sublime-syntax 文件中,我写:

%YAML 1.2
---
name: Metamath
file_extensions: mm
scope: source.mm

contexts:
  main:
    - match: $\([\w\W]*?$\)
      scope: comment

在sublime中查找时匹配正确,在YAML文件中使用时匹配失败。

如有任何关于更好的方法的建议,我们将不胜感激。

您的根本问题是 Sublime 语法高亮显示是逐行进行的,因此任何需要跨多行匹配的正则表达式都不会匹配任何内容,因为它永远无法获得足够的输入。为了执行这种匹配,您需要使用 context stack 逐行跟踪状态。

syntax documentation 有更多关于该主题的信息,但本质上的想法是您临时替换(push 到上下文堆栈)一组针对特定情况的新语法规则,这接管语法突出显示,直到 pop 删除这些规则并返回到之前发生的事情。

您问题中的语法修改示例可能最好地证明了这一点:

%YAML 1.2
---
name: Metamath
file_extensions: mm
scope: source.mm

contexts:
  main:
    - match: $\(
      scope: punctuation.definition.comment.begin
      push:
        - meta_scope: comment
        - match: $\)
          scope: punctuation.definition.comment.end
          pop: true

此处 main 上下文(所有语法匹配开始的地方)中的单个规则只对匹配序列 $\( 感兴趣,因此除此之外的任何文本都将被忽略并最终被纯文本。

$( 匹配时,会发生一些事情。首先,它被分配范围 punctuation.definition.comment.begin 以将其标记为注释开始序列。其次,它将匿名上下文推送到上下文堆栈,规则假定它们在评论中。

虽然此上下文在堆栈上处于活动状态,但唯一适用的 match 规则是该上下文中的规则,它们匹配 $\) 而没有其他。任何不是这个标记的文本都会被忽略,但是当看到那个标记时,它会被分配一个范围,将其标记为评论的结尾,然后 pop 从堆栈中删除这个匿名上下文,去回到评论开始之前的规则(这里只匹配其他评论)

meta_scope 表示虽然此上下文位于堆栈的顶部,但除了它可能具有的任何其他范围之外,所有文本都应被赋予范围 comment。这也适用于导致此上下文被压入的文本($()以及导致上下文被弹出的文本($))。

结果是从 $( 开始到 $) 结束的所有内容,包括那些标记,都被标记为 comment,而开始和结束标记也被分配范围表示他们正在开始评论(不是严格要求,但仍然是一种很好的形式)。

您还可以使用专门命名的 context 项目,而不是此处所示的匿名上下文;通常,对于可能在多个地方需要规则的情况,或者如果只有很多规则需要匹配的情况,这是一种更好的解决方案。

%YAML 1.2
---
name: Metamath
file_extensions: mm
scope: source.mm

contexts:
  main:
    - match: $\(
      scope: punctuation.definition.comment.begin
      push: comment_rules

  comment_rules:
    - meta_scope: comment
    - match: \@\w*
      scope: keyword.other
    - match: $\)
      scope: punctuation.definition.comment.end
      pop: true

此示例与第一个示例大部分相同,但现在 comment_rules 上下文专门命名并按名称使用。有一个额外的条目匹配以 @ 开头的任何单词并以不同方式突出显示它,但仅在评论内部。

通过这种方式,您可以在多种情况下应用评论规则,而不必重复(尽管在本例中这是人为设计的)。

当上下文中有多个规则时,例如在本例中,这样看起来会更清晰一些;对于类似于您的原始示例的内容,可以说匿名上下文更容易阅读,并且使事情更清晰、更独立。