【问题标题】:Remove all whitespaces from String but keep ONE newline从字符串中删除所有空格,但保留一个换行符
【发布时间】:2013-03-07 20:23:06
【问题描述】:

我有这个输入字符串(包含制表符、空格、换行符):


        That      is a test.              
    seems to work       pretty good? working.








    Another test  again.

[编辑]:我应该提供字符串以便更好地测试,因为 stackoverflow 会删除所有特殊字符(制表符,...)

String testContent = "\n\t\n\t\t\t\n\t\t\tDas      ist ein Test.\t\t\t  \n\tsoweit scheint das \t\tganze zu? funktionieren.\n\n\n\n\t\t\n\t\t\n\t\t\t      \n\t\t\t      \n    \t\t\t\n    \tNoch ein  Test.\n    \t\n    \t\n    \t";

我想达到这个状态:


That is a test.
seems to work pretty good? working.
Another test again.

String expectedOutput = "Das ist ein Test.\nsoweit scheint das ganze zu? funktionieren.\nNoch ein Test.\n";

有什么想法吗?这可以使用正则表达式来实现吗?

replaceAll("\\s+", " ") 不是我想要的。如果这个正则表达式能准确地保留现有的 1 个换行符,那将是完美的。

我已经尝试过了,但这对我来说似乎不是最理想的......:

BufferedReader bufReader = new BufferedReader(new StringReader(testContent));
String line = null;
StringBuilder newString = new StringBuilder();
while ((line = bufReader.readLine()) != null) {
    String temp = line.replaceAll("\\s+", " ");
    if (!temp.trim().equals("")) {
        newString.append(temp.trim());
        newString.append("\n");
    }
}

【问题讨论】:

  • 我认为您必须为此制定一些逻辑。您需要在 1 个空格后搜索非空白字符。并在换行后搜索非空格字符..
  • 你想要的逻辑是什么?将连续的空格修剪为 1 个空格?
  • @BlackMaggie 是的,我想总结一下..
  • @zvzdhk 否,因为这不会删除标签,也不会将所有换行符折叠为单个换行符

标签: java string whitespace removing-whitespace


【解决方案1】:

如果我理解正确,您只是想用一个换行符替换一系列换行符。所以用\n(带有适当的标志)替换\n\n*。如果行中有很多空格,只需先删除空格(^\s\s*$ 多行模式),然后替换换行符。

编辑: 这里唯一的问题是一些换行符可能会保留在这里和那里,所以你必须小心首先折叠空格,然后修复空行问题。您可以将其进一步精简为一个可能的正则表达式,但使用这三个更容易阅读:

 Pattern spaces = Pattern.compile("[\t ]+");
 Pattern emptyLines = Pattern.compile("^\\s+$?", Pattern.MULTILINE);
 Pattern newlines = Pattern.compile("\\s*\\n+");
 System.out.print(
      newlines.matcher(emptyLines.matcher(spaces.matcher(
        input).replaceAll(" ")).replaceAll("")).replaceAll("\n"));

【讨论】:

  • 这在我的情况下也可以正常工作:) 将不得不尝试更多的测试数据
【解决方案2】:

你为什么不这样做

String[] lines = split(s,"\n")
String[] noExtraSpaces = removeSpacesInEachLine(lines)
String result = join(noExtraSpaces,"\n")

别忘了https://softwareengineering.stackexchange.com/questions/10998/what-does-the-jamie-zawinskis-quotation-about-regular-expressions-mean

【讨论】:

  • "xx\n \n\n yy" 呢?
  • @MarkoTopolnik 好吧,这取决于您是否需要保留空行或删除它们..
  • @denis.solonenko 很抱歉,stackoverflow 删除了所有特殊字符并将其转换为空格。因此,我刚刚添加了包含所有特殊字符的字符串。
【解决方案3】:

首先用一个新行替换所有新行,然后替换空格不是新行,最后一件事,你应该删除字符串开头的所有空格:

String test = "      This is              a real\n\n\n\n\n\n\n\n\n test !!\n\n\n   bye";
test = test.replaceAll("\n+", "\n");
test = test.replaceAll("((?!\n+)\\s+)", " ");
test = test.replaceAll("((?!\n+)\\s+)", "");

输出:

This is a real
test !!
bye

【讨论】:

  • @MarounMaroun 对我来说它会删除所有空格。我刚刚添加了示例字符串(包含正确的转义字符)。
【解决方案4】:

分四步:

text
    // 1. compress all non-newline whitespaces to single space
    .replaceAll("[\\s&&[^\\n]]+", " ")
    // 2. remove spaces from begining or end of lines
    .replaceAll("(?m)^\\s|\\s$", "")
    // 3. compress multiple newlines to single newlines
    .replaceAll("\\n+", "\n")
    // 4. remove newlines from begining or end of string
    .replaceAll("^\n|\n$", "") 

【讨论】:

  • 我的解决方案的唯一问题是:如果那里有任何空格,则在行尾留下一个空格,如果字符串有任何尾随换行符,则在开头/结尾留下一个换行符。我刚刚修好了(最后我希望:))
【解决方案5】:

在单个正则表达式中(加上标签的小补丁):

input.replaceAll("^\\s+|\\s+$|\\s*(\n)\\s*|(\\s)\\s*", "$1$2")
     .replace("\t"," ");

正则表达式看起来令人生畏,但实际上可以很好地分解为这些经过 OR-ed 的部分:

  • ^\s+ – 匹配开头的空格;
  • \s+$ – 匹配末尾的空格;
  • \s*(\n)\s* – 匹配包含换行符的空格,并捕获该换行符;
  • (\s)\s* – 匹配空格,捕获第一个空格字符。

结果将匹配两个捕获组,但一次可能只有一个组不为空。这让我可以用"$1$2" 替换匹配项,这意味着“连接两个捕获组”。

唯一剩下的问题是我无法使用这种方法将制表符替换为空格,因此我通过简单的非正则表达式字符替换来解决这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-25
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    相关资源
    最近更新 更多