正则表达式可在find中使用,但不能在.sublime-syntax文件中使用

时间:2019-07-03 09:37:19

标签: regex sublimetext3

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

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

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

当我在sublime中的find中使用它时,它正确匹配,但是在YAML文件中使用时失败。

任何有关更好的方法的建议都将受到赞赏。

1 个答案:

答案 0 :(得分:2)

您的潜在问题是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上下文已被专门命名并按名称使用。有一个额外的条目可以匹配以@开头的任何单词,并以不同的方式突出显示该单词,但仅在注释内部。

Sample of syntax in action

通过这种方式,您可以在多种情况下应用注释规则而无需重复操作(尽管在此示例中确实可以做到)。

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