我试图为VSCode编写一个sytnax荧光笔,它使用TextMate格式。我从一个示例中复制了单行注释条目,并且工作正常,但我想扩展/修改它。
"linecomment": {
"name": "comment",
"match": "(%)(?!(\\[=*\\[|\\]=*\\])).*$\n?",
"captures": {
"1": {
"name": "comment"
}
}
},
问题是,这里使用的正则表达式没有记录在我能找到的任何地方。我理解基本的Grep和正则表达式背后的理论,但我不知道?!(\\[=*\\[|\\]=*\\])).*$\n?
中发生了什么。特别是,我不知道哪些字符是正则表达式语言,哪些是匹配的。
有人可以向我解释一下:
答案 0 :(得分:1)
我不知道(1)的答案,但(2)的答案如下:
首先,如果您只使用grep而不使用其他正则表达式,那么您应该知道存在一些语法差异。例如,在大多数风格中,\+
是文字+
,+
是量词;在grep +
中是文字的,\+
是量词。还有其他字符,\
的含义以这种方式反转。
其次,由于反斜杠转义,字符串文字与字符串本身不同。字符串文字如下所示:
"(%)(?!(\\[=*\\[|\\]=*\\])).*$\n?"
虽然字符串本身如下所示:
(%)(?!(\[=*\[|\]=*\])).*$
?
(接近结尾的换行符)。
让我们看看下面的子表达式:
\[=*\[|\]=*\]
起初我以为这是一个由\[
和\]
分隔的字符类。但是(a)我不知道正则表达式的任何风格,其中反斜杠转义的方括号是字符类分隔符,未转义的是正方形括号,而不是相反; (b)为什么有人会写一个带有重复字符的字符类? (c)没有明显的理由说明为什么第一个\]
将是文字]
而第二个将结束字符类。因此看起来\[
和\]
是字面方括号。
|
表示"或"在正则表达式。它是一个低优先级的运算符。因此,此子表达式表示\[=*\[
或\]=*\]
。换句话说,它匹配[[
,[=[
,[======[
等字符串,以及]]
,]=]
等。
(?!...)
是一个零宽度断言。这是一个负向前瞻:它在字符串中的任何一点匹配,其中正向前瞻(?=...)
不匹配。通常,如果正则表达式A
与字符串a
匹配且C
匹配字符串c
,则正则表达式A(?!B)C
匹配字符串ac
,< em>除非正则表达式B
匹配c
(或c
的某些子字符串)。换句话说,如果字符串类似于%]==]
,则匹配失败。
.*
匹配任意数量的字符。 (0是数字)。 (我假设这不匹配换行符。)$
是另一个零宽度断言:它只能在行的末尾匹配。实际上,在这种情况下不需要它 - .*
子表达式是贪婪的并且将匹配所有非换行符,因此.*
匹配的结束保证是结束线。也就是说,除非有一些边缘情况,否则我不知道涉及回车或某些更奇特的线路终止字符。
最后,\n?
将匹配换行符本身,如果它存在(?
是量词)。如果这是字符串的最后一行,那么可能没有换行符;在这种情况下,正则表达式匹配将失败而没有?
。
将所有内容放在一起:正则表达式将从%
匹配到行尾,包括换行符(如果存在),除非它尝试匹配的字符串以{{1开头或%[[
或类似的东西。