【问题标题】:Regex to get text beween curly brackets正则表达式获取大括号之间的文本
【发布时间】:2020-03-14 19:18:02
【问题描述】:

我有一些这样的文件

...some other block above also with a { block }

Main:   Subroutine( )
{ <--
    Include(foo = bar )
    Call(foo = bar )
    Repeat(foo = ibar )
    {
        Message("Message = bar number {ibar}" foo )
        Something( )
        Message("Message = foo {bar}" )
    }
    Message("Message = again  {iterations}" )
    For(start = foo , end = bar  )
    {
        Comment( )
    }
    While(foo )
    {
        Comment( )
    }
    Comment( )
} <--
... some other block below also with a { block }

我需要匹配标有

/^Main:\s*\w*\(\s*\)\s*\{\s*((?:.*\s*)*?)\}$/gm

但它在第一个嵌套块的 } 之后停止,我不知道如何到达最后一个括号。

有什么方法可以匹配直到新行前面的大括号?

谢谢!

编辑:也许我应该补充一下,n 嵌套 { } 块是可能的

【问题讨论】:

  • JS 不支持递归正则表达式,需要解析嵌套的{ ... }。手动执行此操作,找到Main:,然后找到第一个{,然后开始计算{},直到左括号和右括号的数量相等。到此为止。
  • @Thomas 你能提供一个小代码sn-p吗?
  • 也许你可以使用XRegExp ApiXRegExp.matchRecursive(str, '{', '}', 'g'...

标签: javascript regex


【解决方案1】:

许多正则表达式实现不允许用户递归匹配嵌套组。 Javascript不提供PCRE递归参数(?R)see here

改为编写一个小型解析器。

【讨论】:

  • 看起来你正在编写某种编译器?看看this wikipedia article
  • 我猜你是对的。我以为我可以避免编写解析器。谢谢
【解决方案2】:

嵌套结构对于正则表达式来说是一种痛苦,通常最好使用或构建一些解析器来继续执行此类任务。

话虽如此,这里的情况看起来很简单,可以使用一些简单的正则表达式进行匹配。

我将使用^Main:\s*\w*\(\s*\)\s*\{ &lt;--[^}]*(?:\}(?! &lt;--)[^}]*)*\} &lt;--$ 之类的东西。

要点:

  • \{ &lt;-- 匹配左大括号,后跟所需的标记。
  • [^}]* 匹配任何非闭合花括号。
  • (?: 开始非捕获匹配,
    • \} 右花括号,
    • (?! &lt;--) 后面没有标记,
    • [^}]*) 继续匹配任何非闭合花括号。
  • \} &lt;-- 最终匹配标记的右花括号。

【讨论】:

    【解决方案3】:

    如果要获取大括号之间的内容,是否可以使用split方法:

    const str = `Main:   Subroutine( )
    {
        Include(foo = bar )
        Call(foo = bar )
        Repeat(foo = ibar )
        {
            Message("Message = bar number {ibar}" foo )
            Something( )
            Message("Message = foo {bar}" )
        }
        Message("Message = again  {iterations}" )
        For(start = foo , end = bar  )
        {
            Comment( )
        }
        While(foo )
        {
            Comment( )
        }
        Comment( )
    } `
    
    const result = str.split(/[{}]+/)
    console.log(result);

    更新 1:

    我添加了一些数据以使示例数据更加复杂。

    您可以找到所需单词的起始索引,然后制作一个子字符串以提取必要的数据:

    const str = `Main 1 Main:   Subroutine( )
    {
    Include(foo = bar )
    Call(foo = bar )
    Repeat(foo = ibar )
    {
        Message("Message = bar number {ibar}" foo )
        Something( )
        Message("Message = foo {bar}" )
    }
    Message("Message = again  {iterations}" )
    For(start = foo , end = bar  )
    {
        Comment( )
    }
    While(foo )
    {
        Comment( )
    }
    Comment( )
    } `
    
    const strToFind = `Main:   Subroutine( )`;
    const preparedString = str.substring(str.indexOf(strToFind));
    
    const result = preparedString.split(/[{}]+/)
    console.log(result);

    【讨论】:

    • 好点,但我需要先找到主块。源文件包含的不仅仅是主要部分
    • 谢谢。我想这会在我从源文件中得到我需要的一切之后有所帮助
    【解决方案4】:

    试试这个:

    var myString = "Message = {foo} number {bar}"
    var reg = /(?<=\{)\w*(?=\})/g
    var myArray = [...myString.matchAll(reg)]
    console.log(myArray)
    // [['foo'],[bar]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-25
      • 2019-01-20
      • 1970-01-01
      • 2015-05-25
      • 2014-07-31
      相关资源
      最近更新 更多