我需要选择两个外括号之间的所有文本。由于无法确保正则表达式选择匹配括号,因此我编写了以下代码:
public static String getContentBetweenCorresponding(String s, char left, char right) {
int pos = s.indexOf(left);
if ( pos > -1 ) {
int start = pos;
int openCount = 0;
while ( pos < s.length() ) {
char currentChar = s.charAt(pos);
if ( currentChar == right ) {
if ( openCount > 1 ) // if openCount == 1 then correct one
openCount--;
else
return s.substring(start + 1, pos);
} else if ( currentChar == left )
openCount++;
pos++;
}
}
return null;
}
有效。然而,它是无助的慢。我怎样才能加快速度?这个方法需要5s才能完成我的应用程序的瓶颈。
提前多多感谢!
编辑: 我想要做的是在匹配括号之间获取文本。
getContentBetweenCorresponding("bla{{{blubb}}}}}}", '{', '}')
应该返回
"{{blubb}}"
答案 0 :(得分:2)
您编写的方法没有任何明显的低效率。我的猜测实际上问题在于以下其中一个:
s
调用此函数。 如果预计{
和}
之间的距离对于您的实际输入很大,则可以重写方法以使用indexOf
直接查找left
和right
代替为每个角色测试charAt
。在这种情况下,调用indexOf
的次数比调用charAt
少得多,而最外侧括号之间的字符串中的字符将至少检查{{1}的内部实现的两倍。可能会超过JIT使用indexOf
所做的表现。
答案 1 :(得分:1)
这看起来并不太糟糕。你确定这种方法会导致性能问题吗?
您可以尝试紧密循环,以找到下一个打开,关闭或结束。也许转换为char数组而不是charAt
(toCharArray
或更好getChars
)。它至少是用较小的方法获得更好结果的情况。
在更新版本的Java中,substring
将复制支持数组,这种情况不常发生。
所以这就是我如何在没有进行任何基准测试的情况下编写它的性能(!)(可能修改了界面而不是创建String
,甚至可以修改一个) -
public static String betweenMatchedBrackets(
String str, char open, char close
) {
int start = str.indexOf(open);
if (start == -1) {
return null;
}
++start;
int strLen = str.length();
char[] cs = new char[strLen-start]; // Assume typically much of string
strLen.getChars(start, len, cs, 0);
int foundLen = endingBracket(cs, open, closed);
return foundLen != cs.length ? str.substring(start, start+foundLen) : null;
}
private static int endingBracket(char cs, char open, char closed) {
int depth = 1;
int i = 0;
for (; depth != 0 && i != cs.length; ) {
i = nextInteresting(cs, i, open, close);
if (i != cs.length) {
char c = cs[i];
depth += c==open ? 1 : -1;
}
}
return int;
}
private static int nextInteresting(char[] cs, int off, char open, char close) {
for (; off != cs.length && cs[off] != open && cs[off] != close; ++off) {
}
return off;
}
(未进行基准测试或编译。)
答案 2 :(得分:-2)
我认为你不需要编写自己的方法。您可以使用Java正则表达式将括号括起来的字符串。下面的示例代码将为您提供正常括号中间的字符串
String str = "Hello (big) world";
Pattern pattern = Pattern.compile("\\((\\w+)\\)");
Matcher matcher = pattern.matcher(str);
matcher.find();
// result below is "big"
String result = matcher.group(1);