问题描述
我有一个像下面这样的字符串。Sum(Height(In))
我需要像这样拆分上面的字符串。Sum
Height(In)
我尝试过以下正则表达式。但我没有运气。
/[ .:;?!~,`"&|^\((.*)\)$<>{}\[\]\r\n/\\]+/
有什么办法可以实现吗?
提前致谢。
解决方法
您可以匹配第一个 (
之前的所有内容,然后匹配第一个 (
和字符串末尾的 )
之间的所有内容,并使用
const [_,one,two] = "Sum(Height(In))".match(/^([^()]+)\((.*)\)$/);
console.log(`The first value is: ${one},the second is ${two}`);
参见regex demo。如果最后一个 )
不在字符串的末尾,您可以删除字符串的 $
结尾锚点。如果内部可以有换行符,请将 .*
替换为 [\w\W]*
。
正则表达式详情:
-
^
- 字符串的开始 -
([^()]+)
- 第 1 组:除(
和)
之外的一个或多个字符 -
\(
-(
字符 -
(.*)
- 第 2 组:除换行符以外的任何零个或多个字符,尽可能多(*
是贪婪) -
\)
-)
字符 -
$
- 字符串结束。
你可以做到,但方式有限。您需要修复允许的最大括号数(级别数),因为无界情况定义了不规则的语言。正则表达式可以接受正则语言(可通过有限文法解析的语言,称为正则文法或有限状态自动机),而无界级括号语言需要上下文无关文法(并且该算法通常实现为基于堆栈的自动机)。
如果您要接受任何可能具有不平衡括号的表达式(开括号多于闭括号,反之亦然),wiktor Sribizew 的响应所指出的解决方案将是有效的。 em>匹配第一个,那么你需要一个上下文无关语法解析器。有关原因的解释,请参见下文。
为了得到正则表达式,你必须表达什么可以形成最内层(在最高嵌套级别)的正则表达式,不能允许左括号或右括号的东西(对于这个解释,我将在三个层次的括号,但是你可以扩展到更多,唯一的要求是你必须在某个层次上停下来,并且有足够的耐心去做,所以我只在三个层次上做)下面是一个正则表达式允许除括号外的任何内容:
[^()]*
让我称这个表达式为 L0
。允许一对(或一系列)括号匹配......我们可以有第二个正则表达式 L1
,如图所示(符号 {L0}
---我会在周围放一对括号大括号可以让你更好地看到正则表达式中的运算符---表示上面的正则表达式):
{L0} (\( {L0} \) {L0} )*
这意味着一系列 L0
表达式散布着 L0
表达式,每边都有一对括号。我将仅在这种情况下扩展 {L0}
以说明正则表达式如何在每个阶段变得越来越复杂(您可以使用程序构建此正则表达式,您将获得一个非常复杂的正则表达式来解析嵌套括号的数量有限,非常有效)
[^()]* (\( [^()]* \) [^()]* )*
(为了便于阅读,我在大括号周围留了空格,但要使用正则表达式,您需要消除其中的所有嵌入空格)
这个正则表达式可以被称为L1
,它将为我们构建2级正则表达式提供服务。这将由以下序列组成:
{L1} (\( {L1} \) {L1} )*
其中每个 {L1}
都使用我们上面得到的正则表达式进行扩展。此表达式将称为 L2
。
此后,会看到一个模式,对于最多 n
级,您将不得不重复此过程,将 n-1
级表达式替换为 Ln
,即:
{Ln-1} (\( {Ln-1} \) {Ln-1} )*
这个正则表达式将被称为Ln
。正则表达式的总长度在每个嵌套级别至少乘以三倍,因此您可以预期例如嵌套正则表达式的六级括号将包含大约 6*3^(n)
或大约 4375 个字符。如果你有一台计算机,你可以用它来计算正则表达式,你可以编译它并查看它的效率(一次通过,一次只检查一个字符,如果括号最多六级,你会得到括号匹配)
要超过几个级别会给正则表达式带来严重的问题,并且必须使用上下文无关的语法解析器。解析具有 10 级以上括号的 JSON 数据结构很常见,这需要大约 6*3^10
(或大约 360k 个字符长)的正则表达式,这使得这种方法不实用。