【问题标题】:How to replace multiple spaces and newlines with one blank line如何用一个空行替换多个空格和换行符
【发布时间】:2014-01-16 15:23:07
【问题描述】:

如何删除字符串中的多个空格和换行符,但为每组空行保留至少一个空行。

例如,改变:

"This      is



a        string.




Something."

"This is

a string.

Something."

我正在使用.trim() 从字符串的开头和结尾去除空格,但我找不到任何东西可以删除字符串中的多个空格和换行符。

我想只保留一个空格和一个换行符。

【问题讨论】:

    标签: java string string-formatting


    【解决方案1】:

    删除多个空格/换行符的单行解决方案,但从多个空行中保留至少一个空行:

    str = str.replaceAll("(?m)(^ *| +(?= |$))", "").replaceAll("(?m)^$([\r\n]+?)(^$[\r\n]+?^)+", "$1");
    

    每一行也被修剪。


    这是一些测试代码:

    String str = "   This       is\r\n    " + 
            "\r\n" + 
            "   \r\n   " + 
            " \r    \n   \n  " +
            "\r\n" + 
            "                a        string.   ";
    str = str.trim().replaceAll("(?m)(^ *| +(?= |$))", "").replaceAll("(?m)^$([\r\n]+?)(^$[\r\n]+?^)+", "$1");
    System.out.println(str);
    

    输出:

    This is
    
    a string.
    

    【讨论】:

    • 我的头开始在这个正则表达式上冒烟了,+1 虽然是单线
    • 我做个交易:如果你接受这个答案,我会解释正则表达式:)
    • 很遗憾我不是OP所有者,所以我不能接受。我可以通过在Pattern 的 javadoc 中查找那些特殊构造来向自己解释它,但是如果你把你的答案放在其他用户的答案中会更好;-) ...顺便说一句,刚刚测试过,它似乎在最后一行的开头留了一个空格 -> ' a string.'
    • @A4L 我修复了有关前导空格的正则表达式:我将第一个正则表达式中的交替顺序更改为 first 行首的匹配空格,然后如果它们是未找到匹配其他多个空格(正则表达式将按照它们的编码顺序查找替代匹配项)。解释正则表达式需要一段时间。我现在没有时间 - 也许以后(我会告诉你)
    • 谢谢!我会接受这个答案。 A4L写了一个很好的解决方案,但我认为你的单行解决方案更好。
    【解决方案2】:

    前面的建议将修剪所有空格,包括换行符,并用一个空格替换它们。

     text.replaceAll("\\n\\s*\\n", "\\n").replaceAll("[ \\t\\x0B\\f]+", " ").trim());
    

    首先,它用单个换行符替换任何换行符实例,它们之间只有空格,然后将任何其他空格修剪为单个空格,忽略换行符。

    【讨论】:

      【解决方案3】:

      这是我经过一番测试后得出的结论......

      public String keepOneWS(String str) {
          Pattern p = Pattern.compile("(\\s+)");
          Matcher m = p.matcher(str);
      
          Pattern pBlank = Pattern.compile("[ \t]+");
          String newLineReplacement = System.getProperty("line.separator") + 
                  System.getProperty("line.separator");
      
          StringBuffer sb = new StringBuffer();
          while (m.find()) {
              if(pBlank.matcher(m.group(1)).matches()) {
                  m.appendReplacement(sb, " ");   
              } else {
                  m.appendReplacement(sb, newLineReplacement);
              }
          }
          m.appendTail(sb);
      
          return sb.toString().trim();
      }
      
      public void testKeepOneWS()  {
          String str = "   This   \t    is\r\n    " + 
                  "\r\n" + 
                  "   \r\n   " + 
                  " \r    \n  \t  \n  " +
                  "\r\n" + 
                  "                a   \t     string.   \t ";
          String expected = "This is" + System.getProperty("line.separator")+ 
                  System.getProperty("line.separator") + "a string.";
          String actual = keepOneWS(str);
          System.out.println("'" + actual + "'");
          assertEquals(expected, actual);
      }
      

      捕获一组空白后,检查它是否仅包含空格,如果是,则将该组替换为一个空格,否则该组由空格和行终止符组成,在这种情况下,该组被替换由一个行终止符。

      输出是:

      'This is
      
      a string.' 
      

      【讨论】:

      • 谢谢你的回答,如果有两个以上的换行符,我想保留一个空行,并删除其他空行,就像我的例子一样。我知道我的解释不好,因为我写道我只想保留一个空格和一个换行符。我忘记了一个换行符用于新行,而两个换行符用于一个空行。我希望你明白我想说什么。
      • @user3051755,我已经编辑了答案,这对你有用吗?您可以尝试使用正则表达式中的多重性,在上面的示例中,我使用+ 至少一个或多个,您可以使用{2,} 至少两个或更多。
      • 这是我需要的。非常感谢!
      猜你喜欢
      • 1970-01-01
      • 2012-06-04
      • 2011-09-15
      • 1970-01-01
      • 2010-11-19
      • 1970-01-01
      • 2014-01-18
      • 2012-07-06
      • 1970-01-01
      相关资源
      最近更新 更多