使用嵌套正则表达式模式的原子语言定义

Atom Language Definition using nested Regex patterns

我实际上正在尝试在 Atom 中定义一个语法(结果出奇的好),并且在 Regex 摆弄了 3 天之后,感觉慢慢变得疯狂了。

问题是我现在离开了 "simple" 定义领域,所以我还需要比现在更好的正则表达式知识。

问题: 我想使用 beginend 匹配 4 个特定模式。 通过 Textmate 教程,我了解到行为应该有点像:

begin: \w,end: \d 变为 \w(.*)\d

利用这些知识,我想匹配这四个表达式:

  1. foo( a(1) ):解析为嵌套 "in itself" 的作用域(与 TextMate Language Example.
  2. qq-字符串所描述的方式相同
  3. bar(1)('a'):解析为范围 bar,该范围由字段 (1) 访问,因此字段 ('a') 访问。 bar 仅在至少存在第二个括号块的情况下才具有此范围。
  4. foo( bar(1)('a') ):(1)和(2)的混合。 foo是提取的(1),bar代表和(2)中描述的一样的东西。
  5. 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+\((?:.*?(?:\(.*?\))?)+\)(?:\('.*?'\))?