4

如果没有用这种括号 [ ] 包围,我如何用空格分割字符串

所以字符串" book [new interesting book] buy it "应该被分割成

book
new interesting book
buy
it

或者

book
[new interesting book]
buy
it

谢谢!

4

4 回答 4

3

它必须是正则表达式吗?您可以在一次迭代中完成,只需计算空格前有多少个括号,以确定该空格是否应替换为新行标记。

String data="book [new [interesting] book] buy it";
StringBuilder buffer=new StringBuilder();
int bracketCounter=0;
for (char c:data.toCharArray()){
    if (c=='[') bracketCounter++;
    if (c==']') bracketCounter--;
    if (c==' ' && bracketCounter==0)
        buffer.append("\n");
    else 
        buffer.append(c);
}
System.out.println(buffer);

出去:

book
[new [interesting] book]
buy
it
于 2012-06-18T18:45:34.220 回答
2

在这里很难使用String.split(),因为很难区分括号内的空格和括号外的空格。相反,不断地Matcher.find()反对你的字符串,直到你用尽了它的令牌。

List<String> tokens = new ArrayList<String>();
Pattern p = Pattern.compile("\\s*(\\[.*\\]|[^\\s]+)\\s*");
Matcher m = p.matcher(" book [new interesting book] buy it ");
while (m.find()) {
    tokens.add(m.group());
}
System.out.println(tokens);
// Prints: [ book , [new interesting book] , buy , it ]

上面的正则表达式忽略前导和尾随空格,并抓取:(1)任何东西,如果它在括号内或(2)任何非空格序列。

于 2012-06-18T18:47:07.550 回答
2

我改变了一点@cheeken 的回复,只是为了改进一点。由于代码格式,我决定将其包含在答案中:

List<String> tokens = new ArrayList<String>();
Pattern p = Pattern.compile("\\s*(\\[.*\\]|[\\S]*)\\s*");
Matcher m = p.matcher(" book [new interesting book] buy it ");
while (m.find()) {            
    if (!m.group().matches("\\s*")) {    
       tokens.add(m.group());
    }
}

我更改了模式的第二部分,以便使用 \S 的预定义类而不是他的否定,并且我针对空字符串测试了模式,以避免包括他的答案允许的初始和最终空格。

于 2012-06-18T18:54:32.523 回答
0
String input = "foo [bar bar] foo";
Pattern p = Pattern.compile("\[|\]");
String[] s = p.split(input);

现在我们有了[左边的部分,括号内的部分和]右边的部分。现在您可以遍历这些部分(如有必要)并进一步拆分它们。

于 2012-06-18T18:38:19.150 回答