使用嵌套正则表达式模式的{Atom语言定义

时间:2016-09-16 22:27:24

标签: regex coffeescript grammar atom-editor

我实际上是在尝试在Atom中定义一个语法(效果出乎意料的好),并且在使用正则表达式拼凑3天后,感觉慢慢变得疯狂。

问题是我现在离开了“简单”定义的领域,因此我还需要比现在更好的正则表达式知识。

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

begin: \wend: \d变为\w(.*)\d

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

  1. foo( a(1) ):解析为“自身”嵌套的范围(与qq中描述的方式相同 - TextMate Language Example中的字符串。
  2. bar(1)('a'):解析为范围bar,由(1)字段访问,因此字段('a')bar仅在至少存在第二个括号内的条件下具有此范围。
  3. foo( bar(1)('a') ):(1)和(2)的混合物。提取foo(1),bar表示与(2)中描述的内容相同的内容。
  4. foo( bar(1)('a')('a') )('a'):最复杂的一个。 foo表示可以使用第二个括号提取的元素,bar表示可以通过相同机制提取的值,并生成一个值,可以在运行时访问foo而无需进一步的问题
  5. 为了捕获所有这些语句,我现在有两个正则表达式(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的语法。

1 个答案:

答案 0 :(得分:0)

下面这个正则表达式使用递归:

(?<=\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+\((?:.*?(?:\(.*?\))?)+\)(?:\('.*?'\))?