我有这个.feature文件,语法使用以下模式着色:
[
{
"match": '#(.*)$'
"name": 'comment.line.gherkin'
}
{
"match": '^...(.*)$'
"name": 'comment.line.gherkin'
}
{
"match": '(^***.*?***)|((?<=^|)s+***.*?***)'
"name": 'support.class.gherkin'
}
{
"match": '(${.*?})|(@{.*?})'
"name": 'string.single.qoute.gherkin'
}
{
"match": 's*(Scenario:|Feature:|Scenario Outline:|Background:|Examples:)'
"name": 'keyword.gherkin'
}
{
"match": 's*(Given|Then|When|And|But)'
"name": 'support.class.gherkin'
}
{
"match": '(?<=s|^)(@[A-Za-z0-9_-]+)'
"name": 'entity.name.function.decorator.gherkin'
}
{
"begin": '(^[^ t*n|]+)|((?<=^|)s+[^ t*n|]+)'
"end": 's{2}|t|$|s+(?=|)'
"name": 'keyword.gherkin'
}
{
"match": 's(d*)s'
"name": 'entity.name.function.decorator.gherkin'
}
{
"match": '(<w+>)'
"name": 'constant.character.escape.feature'
}
{
"match": "(s'.*?[^']'s)"
"name": 'string.single.qoute.gherkin'
}
{
"match": '(s".*?[^"]"s)'
"name": 'string.double.qoute.gherkin'
}
{
"match": "[('.*?[^']')]"
"name": 'constant.character.escape.feature'
}
{
"match": '([[^]]*])'
"name": 'constant.numeric.gherkin'
}
{
"match": '|s(.*)s|'
"name": 'constant.numeric.gherkin'
}
]
问题是,当我试图使用这种语法高亮编写小文件时(没有完美地遵循小黄瓜结构),regex模式高亮显示'keyword.gherkin'
下的所有内容,直到找到关键字。这是困扰我的模式:
{
"begin": '(^[^ t*n|]+)|((?<=^|)s+[^ t*n|]+)'
"end": 's{2}|t|$|s+(?=|)'
"name": 'keyword.gherkin'
}
如果我删除这些行,它为我所需要的工作,但我然后我失去了一些文本高亮在文件中,如|1|2|3|
,这不是一个真正的解决方案。
让我们举个例子。
请记住,这些正则表达式是不断求值的。
我开始在文档中键入单词Feature:
,当我键入时,它被突出显示为红色。一旦我完成,我继续写,例如Feature: do something
, "Feature:"是红色的,其余的文本成为标准颜色。这才是正确的行为。
例如,如果在文档的开头我开始输入will do something
,它会以红色突出显示,这是不应该的,因为没有任何gherking关键字在那里。
"name":在模式中所做的是建立语法颜色,所以它是不相关的。
我对这个图案做了几次修改,都没有成功。
下面是一个文件示例:https://regex101.com/r/qU5mY5/3
我瞄准错误的模式吗?如果没有,谁能给我点启发?
第一期
不需要的文本被红色高亮显示(will do something
)。
正如您正确指出的,问题位于第二个关键字-regex的第一部分,特别是:
"begin": '(^[^ \t\*\n\|]+)|...'
匹配从开始的 不是:
的所有内容。- a space
' '
- a选项卡
t
- a literal star
*
- a换行
n
- a管道
|
因此,如果一行以will do something
开始,它将匹配直到regex引擎不遇到结束-regex:两个空格s{2}
或制表符t
或行尾$
或"一个或多个空格"后面跟着一个管道s+(?=|)
。
第二期:
如果想匹配完全以|1|2|3|
开头的行,则必须修改begin-regex的第二部分,使用可选的空格s*
,如:
"begin": '...|((?<=^\|)\s*[^ \t\*\n\|]+)'
在线模拟说明这些行为在这里。
这可能会给你足够的信息来解决你的问题,但如果你需要一个具体的解决方案,我需要更多的细节,究竟什么是一个小黄瓜关键字可以除了一个:
'\s*(Scenario\:|Feature\:|Scenario Outline\:|Background\:|Examples\:)'
PS:可能在上面的正则表达式中,冒号不需要转义,可以分组。另外,如果两个字符串有相同的子字符串,请将最长的放在首位以正确匹配(或者始终将 or列表中的元素按从长到短的顺序排列,以便在出现时匹配最长的字符串):
"match": '\s*(Scenario Outline|Background|Examples|Scenario|Feature):'
我已经在线更新了正则表达式以匹配管道表。对于我所读到的和你的例子,下一个正则表达式应该为你工作:
{
"begin": '(|s+[^ t*n|]+)'
"end": '($|s{2}|t|s+(?=|))'
"name": 'keyword.gherkin'
}
在线更新版本HERE
更新2
阅读你链接的gherking文档,我决定你想要占位符,你可以在管道表头突出显示为关键字。Gherkin (红色),而表的数值必须高亮显示为constant.numeric.gherkin。如果是这样的话,你必须用下面的代码替换它们:
{
"match": '|(s*[a-zA-Z][w']+s*|)+s*$'
"name": 'keyword.gherkin'
}
{
"match": '|(s*[d.]+s*|)+s*$'
"name": 'constant.numeric.gherkin'
}
关键字。gherkin匹配任何管道序列| h1 | h2 |...| hn |
,其头由以字母[a-zA-Z]
开头的字组成(可以后跟字母、数字、下划线_
或单引号'
)。
第二个(constant.numeric.gherkin)类似地匹配一个管道序列| N1 | N2 | ... | Nn |
,但字段只能是数字(也是十进制形式的123.25
)。
更新3
查看示例文件,我们可以删除'关键字。修改正则表达式,并更新 constant.numeric。正则表达式如下:{
"match": '|(.+|)+'
"name": 'constant.numeric.gherkin'
}
PS:这个正则表达式突出显示管道表,而不考虑其中的字符。它不再是一个"数字"只有正则表达式,但我认为这是你需要的。