【问题标题】:How to properly trim whitespaces from a string in Java?如何在 Java 中正确修剪字符串中的空格?
【发布时间】:2010-11-29 02:31:06
【问题描述】:

JDK 的 String.trim() 方法非常幼稚,只删除了 ascii 控制字符。

Apache Commons 的 StringUtils.strip() 稍好一些,但使用的是 JDK 的 Character.isWhitespace(),即 doesn't recognize non-breaking space as whitespace

那么在 Java 中修剪字符串的最完整、兼容 Unicode、安全和正确的方法是什么?

顺便说一句,有没有比 commons-lang 更好的库,我应该用它来处理这类事情?

【问题讨论】:

    标签: java string unicode


    【解决方案1】:

    Google 最近提供了guava-librariesmay have 你在找什么:

    CharMatcher.inRange('\0', ' ').trimFrom(str)
    

    相当于String.trim(),但是你可以自定义修剪什么,参考JavaDoc。

    比如它有its own definition of WHITESPACE,它与JDK不同,是根据最新的Unicode标准定义的,所以你需要的可以写成:

    CharMatcher.WHITESPACE.trimFrom(str)
    

    【讨论】:

    • 提示:trimAndCollapseFrom 修剪字符串的外部,同时替换字符串内的重复值。
    【解决方案2】:

    我发誓我是在发布问题后才看到这个:Google 刚刚发布了 Guava,这是一个核心 Java 实用程序库。

    我还没有尝试过,但据我所知,这完全符合 Unicode:

    String s = "  \t testing \u00a0"
    s = CharMatcher.WHITESPACE.trimFrom(s);
    

    【讨论】:

    • 哈哈,我在 5 分钟前提供了相同的答案,但随后对其进行了编辑以包含您需要使用的确切代码,然后看到您自己找到的评论。跨度>
    【解决方案3】:

    很难定义什么是空白。有时我使用不可破坏的空间只是为了确保它不会被剥离。所以很难找到一个库来做你想做的事。

    如果我想修剪每个空白,我会使用我自己的 trim()。这是我用来检查空格的函数,

      public static boolean isWhitespace (int ch)
      {
        if (ch == ' ' || (ch >= 0x9 && ch <= 0xD))
          return true;
        if (ch < 0x85) // short-circuit optimization.
          return false;
        if (ch == 0x85 || ch == 0xA0 || ch == 0x1680 || ch == 0x180E)
          return true;
        if (ch < 0x2000 || ch > 0x3000)
          return false;
        return ch <= 0x200A || ch == 0x2028 || ch == 0x2029
          || ch == 0x202F || ch == 0x205F || ch == 0x3000;
      }
    

    【讨论】:

    • ZZ Coder -- 你说,“很难找到一个库来做你想做的事。”不对!假设您要匹配所有空格 except 一个 \u00a0 (不间断空格)。简单:CharMatcher.WHITESPACE.and(CharMatcher.isNot('\u00a0')).trimFrom(input)
    • @KevinBourrillion 只是想为CharMatcher.WHITESPACE 发送一个大大的“感谢”。 String#trim() 使用 Unicode 失败了。
    【解决方案4】:

    我一直发现trim 几乎适用于所有场景。

    但是,如果您真的想包含更多字符,您可以编辑commons-lang 中的strip 方法,使其不仅包含Character.isWhitespace 的测试,还包含Character.isSpaceChar 似乎是缺少的。即,分别在stripStartstripEnd 处的以下行:

    • while ((start != strLen) &amp;&amp; Character.isWhitespace(str.charAt(start)))
    • while ((end != 0) &amp;&amp; Character.isWhitespace(str.charAt(end - 1)))

    【讨论】:

      【解决方案5】:

      我对 java 的 trim() 方法做了一些小改动,它支持非 ascii 字符。这个方法比大多数实现运行得更快。

      public static String trimAdvanced(String value) {
      
              Objects.requireNonNull(value);
      
              int strLength = value.length();
              int len = value.length();
              int st = 0;
              char[] val = value.toCharArray();
      
              if (strLength == 0) {
                  return "";
              }
      
              while ((st < len) && (val[st] <= ' ') || (val[st] == '\u00A0')) {
                  st++;
                  if (st == strLength) {
                      break;
                  }
              }
              while ((st < len) && (val[len - 1] <= ' ') || (val[len - 1] == '\u00A0')) {
                  len--;
                  if (len == 0) {
                      break;
                  }
              }
      
      
              return (st > len) ? "" : ((st > 0) || (len < strLength)) ? value.substring(st, len) : value;
          }
      

      【讨论】:

        【解决方案6】:

        这可以处理 Unicode 字符并且不需要额外的库:

        String trimmed = original.replaceAll ("^\\p{IsWhite_Space}+|\\p{IsWhite_Space}+$", "");
        

        一个小问题是Wikipedia 中列出了一些没有 Unicode 字符属性“WSpace=Y”的相关空白字符。这些可能不会造成问题,但您也可以轻松地将它们添加到角色类中。

        使用almson-regex,正则表达式将如下所示:

        String trimmed = original.replaceAll (either (START_BOUNDARY + oneOrMore (WHITESPACE), oneOrMore (WHITESPACE) + END BOUNDARY), "");
        

        并包含更相关的非 Unicode 空白。

        【讨论】:

          猜你喜欢
          • 2019-08-19
          • 2011-05-18
          • 1970-01-01
          • 2013-12-15
          • 2010-09-16
          • 2010-10-20
          • 1970-01-01
          • 2021-05-20
          相关资源
          最近更新 更多