VSCode 语法高亮的正则表达式

Regular Expressions particualrs for VSCode Syntax Highlighting

我正在尝试为 VSCode 编写 sytnax 荧光笔,它使用 TextMate 格式。我有一个单行注释条目,是从一个示例中复制的,它工作正常,但我想 extend/modify 它。

"linecomment": {
            "name": "comment",
            "match": "(%)(?!(\[=*\[|\]=*\])).*$\n?",
            "captures": {
                "1": {
                    "name": "comment"
                }
            }
        },

问题是,这里使用的正则表达式在我能找到的任何地方都没有记录。我了解基本的 Grep 和正则表达式背后的理论,但我不知道 ?!(\[=*\[|\]=*\])).*$\n? 中发生了什么。特别是,我不知道哪些字符在正则表达式语言中,哪些正在被匹配。

谁能给我解释一下:

  1. 此处使用了哪种正则表达式格式,记录在何处?
  2. 给定的正则表达式是什么意思,它的组成部分是什么?

我不知道(1)的答案,但是(2)的答案如下:

首先,如果您只使用过 grep 而没有使用过其他形式的正则表达式,您应该知道存在一些语法差异。例如,在大多数风格中,\+ 是文字 ++ 是量词;在 grep + 中是文字,\+ 是量词。还有其他字符\的含义是这样颠倒的。

其次,由于反斜杠转义,字符串文字与字符串本身不同。字符串文字如下所示:

"(%)(?!(\[=*\[|\]=*\])).*$\n?"

而字符串本身看起来像这样:

(%)(?!(\[=*\[|\]=*\])).*$
?

(在末尾附近有一个换行符)。

让我们看看下面的子表达式:

\[=*\[|\]=*\]

起初我以为这是一个字符class,由\[\]分隔。但是(a)我不知道任何正则表达式的风格,其中反斜杠转义的方括号是字符 class 定界符,而未转义的方括号是文字方括号,而不是相反; (b) 为什么有人会用重复的字符写一个字符 class? (c) 没有明显的理由说明为什么第一个 \] 会是文字 ] 而第二个会结束字符 class。所以看起来 \[\] 是文字方括号。

| 在正则表达式中表示 "or"。它是一个低优先级运算符。所以这个子表达式表示 \[=*\[\]=*\]。换句话说,它匹配[[[=[[======[等字符串,以及]]]=]

]

(?!...) 是零宽度断言。这是一个否定的前瞻:它匹配字符串中正前瞻 (?=...) 匹配的任何点。一般来说,如果正则表达式 A 匹配字符串 a 并且 C 匹配字符串 c 那么正则表达式 A(?!B)C 匹配字符串 ac除非 正则表达式 B 匹配 c(或 c 的某个子字符串)。换句话说,如果字符串类似于 %]==].

,则匹配失败

.* 匹配任意数量的字符。 (0 是一个数字)。 (我假设这不匹配换行符。) $ 是另一个零宽度断言:它只能匹配行尾。实际上,在这种情况下不需要它 - .* 子表达式是贪婪的并且会匹配所有非换行符,所以 .* 匹配的结尾保证是行的结尾。也就是说,除非有一些边缘情况,否则我不知道涉及回车 returns 或一些更奇特的行终止字符。

最后,\n? 将匹配换行符本身,如果它存在(? 是量词)。如果这是字符串的最后一行,则可能没有换行符;在这种情况下,如果没有 ?.

正则表达式匹配将失败

综上所述:正则表达式将从 % 匹配到行尾,包括换行符(如果存在),除非它尝试匹配的字符串以 %[[ 开头或 %]==] 或类似的东西。