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)的答案如下:
首先,如果您只使用过 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?
将匹配换行符本身,如果它存在(?
是量词)。如果这是字符串的最后一行,则可能没有换行符;在这种情况下,如果没有 ?
.
正则表达式匹配将失败
综上所述:正则表达式将从 %
匹配到行尾,包括换行符(如果存在),除非它尝试匹配的字符串以 %[[
开头或 %]==]
或类似的东西。
我正在尝试为 VSCode 编写 sytnax 荧光笔,它使用 TextMate 格式。我有一个单行注释条目,是从一个示例中复制的,它工作正常,但我想 extend/modify 它。
"linecomment": {
"name": "comment",
"match": "(%)(?!(\[=*\[|\]=*\])).*$\n?",
"captures": {
"1": {
"name": "comment"
}
}
},
问题是,这里使用的正则表达式在我能找到的任何地方都没有记录。我了解基本的 Grep 和正则表达式背后的理论,但我不知道 ?!(\[=*\[|\]=*\])).*$\n?
中发生了什么。特别是,我不知道哪些字符在正则表达式语言中,哪些正在被匹配。
谁能给我解释一下:
- 此处使用了哪种正则表达式格式,记录在何处?
- 给定的正则表达式是什么意思,它的组成部分是什么?
我不知道(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?
将匹配换行符本身,如果它存在(?
是量词)。如果这是字符串的最后一行,则可能没有换行符;在这种情况下,如果没有 ?
.
综上所述:正则表达式将从 %
匹配到行尾,包括换行符(如果存在),除非它尝试匹配的字符串以 %[[
开头或 %]==]
或类似的东西。