正则表达式如何为我提供输出
来自字符串se,dc(fr(lo)),km(ji)(hn),...
的 az(se)(dc(fr(lo)))(km(ji)(hn))...
有人能告诉我如何编写正则表达式来获取parantheses之间的文本,以便我可以实现上面的结果,而不使用任何外部包/库,因为它仅用于学习目的。
答案 0 :(得分:2)
这是递归正则表达式:
的典型示例\(((?:[^()]++|\((?1)\))*+)\)
让我们打破正则表达式:
\( # Literal (
( # Start of capturing group 1
(?: # Start of non-capturing group
[^()]++ # Match characters other than ()
| # OR
\((?1)\) # Recursively match bracketed () content
)*+ # End of non-capturing group, and repeat the whole group zero or more times.
) # End of capturing group 1
\) # Literal )
开头和结尾的2个文字括号()
是为了确保我们匹配括号内的文字。如果没有它们,它将使用平衡括号匹配部分文本。
(?:[^()]++|\((?1)\))*+
部分描述了一对括号内的模式:
()
字符序列(...)
部分,以(
开头,后跟(?:[^()]++|\((?1)\))*+
(由于(?1)
子程序调用的影响)和以)
结尾。并且可能有0个或多个非括号序列的实例,并且括号内的(...)
部分相互交错。
(?1)
称为子程序调用,它允许您与捕获组分隔的子模式匹配。在这种情况下,由于(?1)
位于捕获组1内部,因此会产生递归效果。
my $str = "az(se)(dc(fr(lo)))(km(ji)(hn))(()aaa(()())(ff(dd)aa))";
my @arr = $str =~ /\(((?:[^()]++|\((?1)\))*+)\)/g;
print join("\n", @arr)
输出
se dc(fr(lo)) km(ji)(hn) ()aaa(()())(ff(dd)aa)
答案 1 :(得分:1)
nhahtdh正则表达式的略短版本:
\(((?:[^()]++|(?R))*+)\)
您可以通过递归到整个表达式((?R)
)而不是子表达式((?1)
)来避免重复文字括号。否则它是一样的。
用作:
my @list = $str =~ /\(((?:[^()]++|(?R))*+)\)/g;