我想要
Match 1: test(testing() tester())
Match 2: theTest()
这
test(testing() tester()) theTest()
我正在使用这个RegExp
/([a-z]+)\((.*)\)/ig
但它是否匹配整个字符串
我认为问题在于.*
,但我无法弄清楚该怎么做
如何让RegExp与大括号相匹配而不与内部大括号相冲突
这是Example
编辑:由于我发现这对于我们正在寻找的东西并非完全可能,是否有一个功能或方法可以完成我想要的东西?
答案 0 :(得分:2)
有趣的问题。是的,JavaScript正则表达式引擎确实无法匹配最外层平衡的匹配括号对,但它可以轻松匹配最里面的平衡对使用以下简单的正则表达式模式:
reInnerParens
/\([^()]*\)/
这种正则表达式可以以迭代的方式有效地使用,以从内到外匹配嵌套的平衡括号。以下有用的测试函数使用此方法来确定字符串是否具有平衡,可能嵌套到任何深度,匹配括号:
function 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实体。一旦完成,那么只剩下所需的最外面的括号。
function 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实体都是可能存在于原始字符串中必须首先受到保护。这是通过在例程开头用&
替换所有&
来完成的,然后在例程结束时将其全部恢复。
答案 1 :(得分:1)
答案 2 :(得分:-1)
String i = "test(testing() tester()) theTest()";
String regex = "\\w+\\(\\w+\\(\\)\\s\\w+\\(\\)\\)|\\w+\\(\\)";
p = Pattern.compile(regex);
m = p.matcher(i);
if (m.find()) {
System.out.println(m.group());
}
尝试使用此正则表达式,如果您的文字只是这么多。
答案 3 :(得分:-1)
使用以下正则表达式:
/[a-z]+\(([a-z]+\(\) [a-z]+\(\))*\)/gi
完整代码:
str.match(/[a-z]+\(([a-z]+\(\) [a-z]+\(\))*\)/gi);
O / P:
["test(testing() tester())", "theTest()"]