是否有一种方法只匹配顶级括号与regex

Is there a way to match only top level parentheses with regex?

本文关键字:regex 方法 一种 是否      更新时间:2023-09-26

使用Javascript,假设我有一个像(1)(((2)(3))4)这样的字符串,我可以得到一个正则表达式来匹配(1)(((2)(3))4),或者我需要做一些更复杂的事情吗?

理想情况下,如果搜索((2)(3))4,正则表达式将返回["((2)(3))","4"]。实际上这是一个必要条件。关键是要把事情分成需要先处理的块,就像数学中的括号一样。

No, there is no way to match only top level parentheses with regex

只看顶层并不比一般递归结构的"解析"更容易解决问题。(看看这个相关的流行问题和一个很好的答案)。

为什么Regex不能解析任意层次的嵌套:

为了跟踪嵌套的级别,必须计数。如果希望能够跟踪任意级别的嵌套,则在运行程序时需要一个任意大的数字。

但是正则表达式正是那些可以由DFAs实现的,即确定性有限自动机。它们只有一个有限数量的状态。因此,它们无法跟踪任意大的

此参数也适用于您只对顶层括号感兴趣的特定关注点。

要识别顶级圆括号,必须跟踪任意一个圆括号前面的任意嵌套:

((((..arbitrarily deep nesting...))))((.....)).......()......
^toplevel                           ^^       ^       ^^

所以,是的,你需要一些比正则表达式更强大的东西。


如果你是非常务实的,对于你的具体应用程序来说,你可能会说你不会遇到任何嵌套深度超过1000的嵌套(所以你可能愿意使用regex),这也是一个非常实际的事实,任何识别嵌套级别超过2的regex基本上都是不可读的。

好吧,这里有一种方法。正如Jo So指出的那样,你不能在javascript中使用无限的递归,但是你可以很容易地实现任意递归。但我不确定性能是如何衡量的。

首先我发现你需要递归。然后我意识到,你可以让你的正则表达式"递归"只需复制和递归粘贴,像这样(使用花括号清晰):

regex开始

查找括号中不是括号的内容。

/{([^{}])*}/g

然后复制并粘贴整个正则表达式!(我把它隔开了,这样你就能看到它是贴在哪里的。)现在基本上就是a( x | a( x )b )b

/{([^{}] | {([^{}])*} )*}/g

这将给你一级递归,你可以继续以这种方式,每次递归的数量实际上翻倍:

//matches {4{3{2{1}}}}
/{([^{}]|{([^{}]|{([^{}]|{([^{}])*})*})*})*}/g
//matches {8{7{6{5{4{3{2{1}}}}}}}}
/{([^{}]|{([^{}]|{([^{}]|{([^{}]|{([^{}]|{([^{}]|{([^{}]|{([^{}])*})*})*})*})*})*})*})*}/g

最后,我只是在表达式的末尾添加|[^{}]+来匹配完全在括号之外的东西。很疯狂,但能满足我的需要。我觉得可能有一些聪明的方法将这个概念与递归函数结合起来,以获得一个真正的递归匹配器,但我现在想不起来。

如果 可以肯定的是,括号是平衡(我敢肯定还有其他的资源,能为你回答这个问题如果需要)如果"顶级"你高兴找到本地以及全球maxima 然后所有你需要做的是找到任何内容,从一个开放的支架和关闭一个右括号,两者之间没有中间开括号:

我认为下面的内容可以帮你做到这一点,并且可以帮助你对任何"顶级"内容进行分组:

'(([^'(]*?)')

这些内容可能并不都在同一"级别",但是如果您将嵌套的括号视为描述树的分支,则正则表达式将返回给您叶子。如果您对文本进行预处理,将其包装在括号中,并且满足前面的假设,则可以保证始终获得至少一个"叶子"。