花括号内的文本正则表达式获取

3

我有某种类型的这个文件

...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 个嵌套的 { } 块。


1
JS不支持递归正则表达式,你需要手动解决嵌套的{...}。找到“Main:”,然后找到第一个“{”,开始计数“{”和“}”,直到开放和关闭括号的数量相等为止。这样就可以得到你想要的结果了。 - Thomas
@Thomas,你能否提供一小段代码片段吗? - shiiboun
也许你可以使用XRegExp ApiXRegExp.matchRecursive(str, '{', '}', 'g'... - bobble bubble
4个回答

1
许多正则表达式实现不允许用户递归匹配嵌套的组。Javascript 不提供 PCRE 递归参数 (?R) 参见此处。请编写一个小的解析器代替它。

看起来你正在编写某种类型的编译器?可以参考一下这篇维基百科文章 - Edd
我想你是对的。我以为我可以避免编写解析器。 - shiiboun

1
如果您想获取花括号之间的内容,那么可以使用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);


好的观点,但我需要先找到主块。源文件包含的不仅仅是主要部分。 - shiiboun
谢谢。我想这会在我从源文件中获取所有需要的内容后有所帮助。 - shiiboun

1
嵌套结构对于正则表达式来说是一种痛苦,通常最好使用或构建一些解析器来处理这样的任务。 话虽如此,这里的情况看起来足够简单,可以使用一些简单的正则表达式进行匹配。 我会使用类似于^Main:\s*\w*\(\s*\)\s*\{ <--[^}]*(?:\}(?! <--)[^}]*)*\} <--$的东西。 关键点: - \{ <--匹配一个左花括号后面跟着所需的标记。 - [^}]* 匹配任何非闭合花括号。 - (?: 开始非捕获匹配, - \} 一个闭合花括号, - (?! <--) 不跟在标记后面, - [^}]*) 继续匹配任何非闭合花括号。 - \} <-- 最后匹配标记的闭合花括号。

0

试试这个:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接