Java字符串 - 按空格拆分,但保留双空格

3

目前我正在通过空格来分割字符串。但是有一些双空格我想在将它们全部组合在一起时保留下来。有什么建议吗?

例如,字符串"I went to the beach. I ate pie"被分割为

I
went
to
the
beach.

I
ate
pie

我不想要空白条目,但我希望将其按照相同的格式重新组合。感谢大家!

听起来你可以使用StringTokenizer(按空格拆分),并在任何非字母字符后添加一个空格。 - Nir Alfasi
你能保留每个标记末尾的空格吗?这将有一个非常简单的编程解决方案。 - Marko Topolnik
5个回答

3

可以使用String的replaceAll(" ", " unlikelyCharacterSequence")方法将字符串中的双空格替换为一个不太可能出现的字符序列,然后按照正常方式通过空格对字符串进行分割。最后,您可以通过在末尾将{unlikelyCharacterSequence}替换为双空格来将其转换回去。

但是:如果您在实际未修改的字符串中遇到了您的“不太可能”的字符序列,则此方法会失败。为了更通用的解决方案,请查看下面这个示例的备选方案。

示例(警告,取决于不存在!@ #!@#:)

String example = "Hello.  That was a double space. That was a single space."
String formatted = example.replace("  ", " !@#!@#");
String [] split = formatted.split(" ");
for(int i = 0; i < split.length; i++)
{
  split.replace("!@#!@#", " ");
}
// Recombine your splits?

或者你可以采取更为稳健的策略,将字符串按照你在问题中所给出的方式重新组合,但忽略只包含单个空格的元素:

String example = "ThisShouldBeTwoElements.  ButItIsNot.";
String [] splitString = example.split(" ");
String recombined = "";
for(int i = 0; i < splitString.length; i++)
{
  if(!splitString[i].equals(" "))
    recombined += splitString[i];
}

3
如果字符串中包含字符 %,该怎么办? - P.P
1
@KingsIndian,所以将%替换为%%% :))) - Nir Alfasi
3
@BlackVegetable,你这个{!@#@!#}疯了。 :P - Andrew
我的逻辑有错误吗?我收到了一个踩。虽然我不介意,但如果需要的话,我想提供一个更好的答案。 - BlackVegetable
@Voo 很好,我同意。是删除我的回答中的那部分内容更好呢,还是将其保留作为谷歌用户可能存在的错误解决方案的示例呢? - BlackVegetable
显示剩余7条评论

2

1
仔细研究一下Java的正则表达式可以为你带来什么好处。使用正则表达式可以识别模式的方法。

Java正则表达式示例


1

请尝试使用此方法,它可以删除非空格字符之间的所有空格。

myString = myString.replaceAll("\S\s\S", "");

这将在两个单词之间出现多个空格时保留它们。


1

我知道这是一个老问题,但是为了未来的读者受益:你要寻找的概念是“捕获组”。捕获组允许您引用表达式中的匹配项,并稍后检索它们,例如通过反向引用,而不是字符串被吞噬。

从文档中,这是您需要了解的相关语法:

(?<name>X)          X, as a named-capturing group
(?:X)               X, as a non-capturing group
(?idmsuxU-idmsuxU)  Nothing, but turns match flags i d m s u x U on - off
(?idmsux-idmsux:X)  X, as a non-capturing group with the given flags i d m s u x on - off
(?=X)               X, via zero-width positive lookahead
(?!X)               X, via zero-width negative lookahead
(?<=X)              X, via zero-width positive lookbehind
(?<!X)              X, via zero-width negative lookbehind
(?>X)               X, as an independent, non-capturing group

使用输入文本:

String example = "ABC     DEF     GHI J K";

你可以使用正向和负向先行断言的组合,将尾随空格与每个单词结合起来:
// Result: [ABC     , DEF     , GHI , J , K]
example.split("(?<=\\s+)(?!\\s)");

或者您可以使用正向先行断言来捕获单词边界,以保留空格作为单独的、分组的元素:
// Result: [ABC,      , DEF,      , GHI,  , J,  , K]
example.split("(?=\\b)");

Java模式API:
http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
顺便提一下: 虽然“用完全不合理的东西替换文本”的建议很诱人,因为它很容易实现,但在生产代码中千万不要这样做。它最终肯定会失败,而且它发生的频率比你想象的要高。我曾经调试过一个呼叫中心,因为一个程序员使用了大约80列的“~=$~=$~=$...”相信这是安全的。那持续了几个月,直到一个服务代表只用这个序列保存了他的笔记上的“花式边框”。我甚至见证过一个真正的、随机的MD5碰撞在搜索服务器上发生。当然,这个MD5碰撞花了11年的时间,但它仍然导致了搜索崩溃,这个观点仍然存在。唯一的字符串从来没有。永远假设重复出现。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接