假设
从问题来看,假设是嵌套括号不超过 2 级。还假设括号是平衡的。
我进一步假设您不允许转义[]
.
我还假设当有嵌套括号时,只保留内括号的第一个左括号[
和最后一个右括号。]
其余部分,即顶层支架和内部支架的其余部分被移除。
例如:
only[single] [level] outside[text more [text] some [text]moreeven[more]text[bracketed]] still outside
更换后会变成:
onlysingle level outsidetext more [text some textmoreevenmoretextbracketed] still outside
除了上述假设之外,没有其他假设。
如果您可以对括号前后的间距做出假设,那么您可以使用Denomales 提供的更简单的解决方案。否则,我下面的解决方案将在没有这种假设的情况下工作。
解决方案
private static String replaceBracket(String input) {
// Search for singly and doubly bracketed text
Pattern p = Pattern.compile("\\[((?:[^\\[\\]]++|\\[[^\\[\\]]*+\\])*+)\\]");
Matcher matcher = p.matcher(input);
StringBuffer output = new StringBuffer(input.length());
while (matcher.find()) {
// Take the text inside the outer most bracket
String innerText = matcher.group(1);
int startIndex = innerText.indexOf("[");
int endIndex;
String replacement;
if (startIndex != -1) {
// 2 levels of nesting
endIndex = innerText.lastIndexOf("]");
// Remove all [] except for first [ and last ]
replacement =
// Text before and including first [
innerText.substring(0, startIndex + 1) +
// Text inbetween, stripped of all the brackets []
innerText.substring(startIndex + 1, endIndex).replaceAll("[\\[\\]]", "") +
// Text after and including last ]
innerText.substring(endIndex);
} else {
// No nesting
replacement = innerText;
}
matcher.appendReplacement(output, replacement);
}
matcher.appendTail(output);
return output.toString();
}
解释
这里唯一值得解释的是正则表达式。其余的你可以查看Matcher类的文档。
"\\[((?:[^\\[\\]]++|\\[[^\\[\\]]*+\\])*+)\\]"
以 RAW 形式(当您打印出字符串时):
\[((?:[^\[\]]++|\[[^\[\]]*+\])*+)\]
让我们把它分解(空格无关紧要):
\[ # Outermost opening bracket
( # Capturing group 1
(?:
[^\[\]]++ # Text that doesn't contain []
| # OR
\[[^\[\]]*+\] # A nested bracket containing text without []
)*+
) # End of capturing group 1
\] # Outermost closing bracket
我使用了所有格量词*+
,++
以防止正则表达式引擎回溯。具有正常贪心量词的版本\[((?:[^\[\]]+|\[[^\[\]]*\])*)\]
仍然可以工作,但效率会稍低,并且可能会导致StackOverflowError
足够大的输入。