使用嵌套正则表达式模式的原子语言定义
Atom Language Definition using nested Regex patterns
我实际上正在尝试在 Atom 中定义一个语法(结果出奇的好),并且在 Regex 摆弄了 3 天之后,感觉慢慢变得疯狂了。
问题是我现在离开了 "simple" 定义领域,所以我还需要比现在更好的正则表达式知识。
问题:
我想使用 begin
和 end
匹配 4 个特定模式。
通过 Textmate 教程,我了解到行为应该有点像:
begin: \w
,end: \d
变为 \w(.*)\d
利用这些知识,我想匹配这四个表达式:
foo( a(1) )
:解析为嵌套 "in itself" 的作用域(与 TextMate Language Example. 中 qq
-字符串所描述的方式相同
bar(1)('a')
:解析为范围 bar
,该范围由字段 (1)
访问,因此字段 ('a')
访问。 bar
仅在至少存在第二个括号块的情况下才具有此范围。
foo( bar(1)('a') )
:(1)和(2)的混合。 foo
是提取的(1),bar
代表和(2)中描述的一样的东西。
foo( bar(1)('a')('a') )('a')
:最复杂的一个。 foo
表示可以使用第二个括号提取的元素,bar
表示可以通过相同机制提取的内容并产生可以访问 foo
的值,而不会在运行时出现进一步问题.
为了捕获所有这些语句,我现在有两个正则表达式(遵循 CSON 语法):
'strange_accessors':
{
'comment': 'tries to catch foo(a)(a)(a) constructs'
'begin': '(?:' +
'(?:(?<=\))\s*)' + # closing parenthesis beforehand
'|(?:[\w%\$\?!#]*)' + # character beforehand
')' +
'\s*' +
'(\()' + # opening bracket
'[^;]+?' +
'(\))' +
'\s*(\()'
'end': '(\))+?'
'beginCaptures':
'1':
'name': 'punctuation.parens.begin.someLang'
'2':
'name': 'punctuation.parens.someLang'
'3':
'name': 'punctuation.parens.begin.someLang'
'endCaptures':
'0':
'name': 'punctuation.parens.end.someLang'
}
所以,为了捕捉周围的括号,我使用这个:
'surronding_parenthesis':
{
'comment': 'describes a (nested) accessor using parenthesis'
'begin': '(?:[a-zA-Z_%\$\?!#][\w%\$\?!#]*)' + # character beforehand
'(\()'
'end': '(?>(\)))'
'beginCaptures':
'1':
'name': 'punctuation.section.parens.begin.someLang'
'endCaptures':
'1':
'name': 'punctuation.section.parens.end.someLang'
'2':
'name': 'banana.invalid.illegal.someLang'
'patterns':[
{ 'include': '#strange_accessors'}
]
}
我在贪婪、不情愿和占有欲行为以及原子组中摆弄自己的方式,因为我认为这将是良好匹配的关键。
但是我很困惑,不知道如何解决这个奇怪的嵌套问题。如果有人感兴趣并想尝试为什么我需要这个:
这是 Scilab 的语法。
下面这个正则表达式使用了递归:
(?<=\s)\w+(\(((?:[^()]+|(?1))*?)\))(\('.*?'\))?
它将匹配
foo( a(1) )
bar(1)('a')
foo( bar(1)('a') )
foo( bar(1)('a')('a') )('a')
你可以测试一下here on regex101
(Scilab 使用我在论坛上看到的 PCRE 正则表达式引擎)
请注意,它包含正后视 (?<=\s)
以确保前导词之前有一个空格。
因为我怀疑你想匹配 \b( a(1) )
这样的东西
此正则表达式也将匹配它们,但没有递归。仅使用非捕获组:
(?<=\s)\w+\((?:.*?(?:\(.*?\))?)+\)(?:\('.*?'\))?
我实际上正在尝试在 Atom 中定义一个语法(结果出奇的好),并且在 Regex 摆弄了 3 天之后,感觉慢慢变得疯狂了。
问题是我现在离开了 "simple" 定义领域,所以我还需要比现在更好的正则表达式知识。
问题:
我想使用 begin
和 end
匹配 4 个特定模式。
通过 Textmate 教程,我了解到行为应该有点像:
begin: \w
,end: \d
变为 \w(.*)\d
利用这些知识,我想匹配这四个表达式:
foo( a(1) )
:解析为嵌套 "in itself" 的作用域(与 TextMate Language Example. 中 bar(1)('a')
:解析为范围bar
,该范围由字段(1)
访问,因此字段('a')
访问。bar
仅在至少存在第二个括号块的情况下才具有此范围。foo( bar(1)('a') )
:(1)和(2)的混合。foo
是提取的(1),bar
代表和(2)中描述的一样的东西。foo( bar(1)('a')('a') )('a')
:最复杂的一个。foo
表示可以使用第二个括号提取的元素,bar
表示可以通过相同机制提取的内容并产生可以访问foo
的值,而不会在运行时出现进一步问题.
qq
-字符串所描述的方式相同
为了捕获所有这些语句,我现在有两个正则表达式(遵循 CSON 语法):
'strange_accessors':
{
'comment': 'tries to catch foo(a)(a)(a) constructs'
'begin': '(?:' +
'(?:(?<=\))\s*)' + # closing parenthesis beforehand
'|(?:[\w%\$\?!#]*)' + # character beforehand
')' +
'\s*' +
'(\()' + # opening bracket
'[^;]+?' +
'(\))' +
'\s*(\()'
'end': '(\))+?'
'beginCaptures':
'1':
'name': 'punctuation.parens.begin.someLang'
'2':
'name': 'punctuation.parens.someLang'
'3':
'name': 'punctuation.parens.begin.someLang'
'endCaptures':
'0':
'name': 'punctuation.parens.end.someLang'
}
所以,为了捕捉周围的括号,我使用这个:
'surronding_parenthesis':
{
'comment': 'describes a (nested) accessor using parenthesis'
'begin': '(?:[a-zA-Z_%\$\?!#][\w%\$\?!#]*)' + # character beforehand
'(\()'
'end': '(?>(\)))'
'beginCaptures':
'1':
'name': 'punctuation.section.parens.begin.someLang'
'endCaptures':
'1':
'name': 'punctuation.section.parens.end.someLang'
'2':
'name': 'banana.invalid.illegal.someLang'
'patterns':[
{ 'include': '#strange_accessors'}
]
}
我在贪婪、不情愿和占有欲行为以及原子组中摆弄自己的方式,因为我认为这将是良好匹配的关键。
但是我很困惑,不知道如何解决这个奇怪的嵌套问题。如果有人感兴趣并想尝试为什么我需要这个:
这是 Scilab 的语法。
下面这个正则表达式使用了递归:
(?<=\s)\w+(\(((?:[^()]+|(?1))*?)\))(\('.*?'\))?
它将匹配
foo( a(1) )
bar(1)('a')
foo( bar(1)('a') )
foo( bar(1)('a')('a') )('a')
你可以测试一下here on regex101
(Scilab 使用我在论坛上看到的 PCRE 正则表达式引擎)
请注意,它包含正后视 (?<=\s)
以确保前导词之前有一个空格。
因为我怀疑你想匹配 \b( a(1) )
此正则表达式也将匹配它们,但没有递归。仅使用非捕获组:
(?<=\s)\w+\((?:.*?(?:\(.*?\))?)+\)(?:\('.*?'\))?