我正在努力获取
Match 1: test(testing() tester())
Match 2: theTest()
来自
测试(testing() tester()) theTest()
我正在使用这个正则表达式
/([a-z]+)\((.*)\)/ig
但是它是否匹配整个字符串
我认为问题出在 .*
但我不知道该怎么做
如何让正则表达式匹配大括号而不与内部大括号冲突
这是一个Example
编辑:由于我发现这对于我正在寻找的东西来说并不完全可能,是否有一个函数或方法可以完成我正在寻找的东西?
最佳答案
有趣的问题。是的,JavaScript 正则表达式引擎确实无法匹配最外面一对平衡的括号,但是它可以使用以下方法轻松匹配最里面平衡对以下简单的正则表达式模式:
reInnerParens
/\([^()]*\)/
此正则表达式可以以迭代方式有效地使用,以从内到外匹配嵌套的平衡括号。以下有用的测试函数使用此方法来确定字符串是否平衡,可能嵌套到任何深度,匹配括号:
函数 isBalancedParens(text)
function isBalancedParens(text) {
var reInnerParens = /\([^()]*\)/g;
// Iteratively remove balanced pairs from inside out.
while (text.search(reInnerParens) !== -1) {
text = text.replace(reInnerParens, '');
}
// Any remaining parens indicate unbalanced pairs.
if (/[()]/.test(text)) return false;
return true;
}
上述函数的工作原理是从内到外迭代地删除最里面的平衡括号,直到不再有匹配项为止。如果还有剩余的括号,则该字符串包含不匹配的括号并且不平衡。
可以使用类似的迭代技术来解决当前的问题。首先,需要一个正则表达式来匹配一对平衡的括号,其中至少包含一对内部括号,但仅嵌套一层深。这是自由间距模式格式:
reOuterParens
/* reOuterParens
# Match outer parens having inner parens one level deep.
\( # Outer open paren.
( # $1: Contents of outer parens .
(?: # One or more nested parens (1 deep).
[^()]* # Zero or more non-parens.
\( # Inner open paren.
[^()]* # Zero or more non-parens.
\) # Inner close paren.
)+ # One or more nested parens (1 deep).
[^()]* # Zero or more non-parens.
) # End $1: Contents of outer parens .
\) # Outer close paren.
*/
var reOuterParens = /\(((?:[^()]*\([^()]*\))+[^()]*)\)/g;
以下经过测试的 JavaScript 函数迭代地应用此正则表达式来将所有内括号“隐藏”为 HTML 实体。一旦完成,就只剩下所需的最外面的括号。
函数 getOutermostParens(text)
// Match and return all outermost "word(..(..))" patterns from string.
function getOutermostParens(text) {
var reOuterParens = /\(((?:[^()]*\([^()]*\))+[^()]*)\)/g;
var results = [];
// Ensure all (possibly nested) matching parentheses are properly balanced.
if (!isBalancedParens(text)) return null;
text = text.replace(/&/g, '&') // Temporarily hide html entities.
// Iteratively hide all parens nested one level deep.
while (text.search(reOuterParens) !== -1) {
// Hide nested parens by converting to html entities.
text = text.replace(reOuterParens,
function(m0, m1){
m1 = m1.replace(/[()]/g,
function(n0){
return {'(':'(', ')': ')'}[n0];
});
return '('+ m1 +')';
});
}
// Match all outermost "word(...)" and load into results array.
text.replace(/\w+\([^()]*\)/g,
function(m0){
m0 = m0.replace(/[01];/g, // Restore hidden parens.
function(n0){
return {'(': '(', ')': ')'}[n0];
});
// Restore temporarily hidden html entities.
m0 = m0.replace(/&/g, '&');
results.push(m0);
return ''; // Not used.
});
return results;
}
请注意,内部嵌套的 ()
括号字符通过将其替换为 HTML 实体等效项(即 (
和 )
),但为了安全地执行此操作,必须首先保护原始字符串中可能存在的所有 HTML 实体。这是通过在例程开始时用 &
替换所有 &
来完成的,然后这些都在例程结束时恢复。
关于JavaScript 正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20977220/