【问题标题】:Trim a string based on the string length根据字符串长度修剪字符串
【发布时间】:2012-01-19 22:41:08
【问题描述】:

如果长度超过 10 个字符,我想修剪一个字符串。

假设如果字符串长度为 12 (String s="abcdafghijkl"),那么新修剪的字符串将包含"abcdefgh.."

我怎样才能做到这一点?

【问题讨论】:

标签: java string


【解决方案1】:
s = s.substring(0, Math.min(s.length(), 10));

像这样使用Math.min可以避免在字符串已经比10短的情况下出现异常。


注意事项:

  1. 上面做了简单的修剪。如果字符串太长,你真的想用三个点替换最后一个字符,请使用 Apache Commons StringUtils.abbreviate;见@H6 的solution。如果您想使用 Unicode 水平省略号字符,请参阅 @Basil 的 solution

  2. 对于String 的典型实现,s.substring(0, s.length()) 将返回s,而不是分配一个新的String

  3. 如果您的字符串包含 BMP 之外的 Unicode 代码点,这可能会出现错误1;例如表情符号。有关适用于所有 Unicode 代码点的(更复杂的)解决方案,请参阅 @sibnick 的 solution


1 - 不在平面 0(BMP)上的 Unicode 代码点在 String 中表示为“代理对”(即两个 char 值)。通过忽略这一点,我们可能会将字符串修剪为少于 10 个代码点,或者(更糟糕的是)在代理对的中间截断它。另一方面,String.length() 不是衡量 Unicode 文本长度的好方法,因此基于该属性进行修剪可能是错误的做法。

【讨论】:

  • 我们不能进行条件检查并仅在字符串为最大值时才进行子字符串,而不是 Math.min 吗?例如:s = (s.length() > 10) ? s.substring(0,10) : s ;
  • 是的,当然可以。阅读其他答案以了解解决问题的其他方法!
  • @rram 如果你进入 substring 方法,你会看到,这个行为实际上是在幕后完成的。
【解决方案2】:

来自Apache Commons Lang库的StringUtils.abbreviate可能是你的朋友:

StringUtils.abbreviate("abcdefg", 6) = "abc..."
StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
StringUtils.abbreviate("abcdefg", 4) = "a..."

Commons Lang3 甚至允许将自定义字符串设置为替换标记。例如,您可以使用它设置单个字符省略号。

StringUtils.abbreviate("abcdefg", "\u2026", 6) = "abcde…"

【讨论】:

  • 可能是,但 OP 的问题并没有要求“省略号”。
  • @StephenC - 该问题显示 8 个字符后跟 2 个点,长度限制为 10,这很像省略号(只有 2 个点而不是 3 个)。许多发现这个问题的人也可能认为省略号很有用。
  • ...如果你不想要省略号,那么 StringUtils.left() 可以帮助你。
  • 仅供参考,HORIZONTAL ELLIPSIS 是单个字符,而不是三个 FULL STOP 字符:……
【解决方案3】:

有一个 Apache Commons StringUtils 函数可以做到这一点。

s = StringUtils.left(s, 10)

如果 len 个字符不可用,或者 String 为 null,则 String 将无异常返回。如果 len 为负数,则返回一个空字符串。

StringUtils.left(null, ) = null
StringUtils.left(
, -ve) = ""
StringUtils.left("", *) = ""
StringUtils.left("abc", 0) = ""
StringUtils.left("abc", 2) = "ab"
StringUtils.left("abc", 4) = "abc"

StringUtils.Left JavaDocs

礼貌:斯蒂夫·麦考利

【讨论】:

    【解决方案4】:

    像往常一样,没有人关心 UTF-16 代理对。看看他们:What are the most common non-BMP Unicode characters in actual use? 即使是 org.apache.commons/commons-lang3 的作者

    您可以在此示例中看到正确代码和普通代码之间的区别:

    public static void main(String[] args) {
        //string with FACE WITH TEARS OF JOY symbol
        String s = "abcdafghi\uD83D\uDE02cdefg";
        int maxWidth = 10;
        System.out.println(s);
        //do not care about UTF-16 surrogate pairs
        System.out.println(s.substring(0, Math.min(s.length(), maxWidth)));
        //correctly process UTF-16 surrogate pairs
        if(s.length()>maxWidth){
            int correctedMaxWidth = (Character.isLowSurrogate(s.charAt(maxWidth)))&&maxWidth>0 ? maxWidth-1 : maxWidth;
            System.out.println(s.substring(0, Math.min(s.length(), correctedMaxWidth)));
        }
    }
    

    【讨论】:

    【解决方案5】:

    s = s.length() > 10 ? s.substring(0, 9) : s;

    【讨论】:

    • 子字符串的第二个参数是排他的,所以这个答案将字符串修剪为9个字符。
    【解决方案6】:

    如果你手头没有StringUtils,你也可以使用这个方法:

    public static String abbreviateString(String input, int maxLength) {
        if (input.length() <= maxLength) 
            return input;
        else 
            return input.substring(0, maxLength-2) + "..";
    }
    

    【讨论】:

    • 您的代码对我不起作用。试试这个System.out.println(abbreviateString("ABC\ud83d\udc3bDEF", 6));
    【解决方案7】:

    以防万一您正在寻找一种方法来修剪和保留字符串的最后 10 个字符。

    s = s.substring(Math.max(s.length(),10) - 10);
    

    【讨论】:

      【解决方案8】:

      tl;博士

      截断时,您似乎要求在最后一个位置添加 ellipsis () 字符。这是操作输入字符串的单行代码。

      String input = "abcdefghijkl";
      String output = ( input.length () > 10 ) ? input.substring ( 0 , 10 - 1 ).concat ( "…" ) : input;
      

      看到这个code run live at IdeOne.com.

      abcdefghi…

      三元运算符

      我们可以使用ternary operator 来制作单线。

      String input = "abcdefghijkl" ;
      
      String output = 
          ( input.length() > 10 )          // If too long…
          ?                                
          input     
          .substring( 0 , 10 - 1 )         // Take just the first part, adjusting by 1 to replace that last character with an ellipsis.
          .concat( "…" )                   // Add the ellipsis character.
          :                                // Or, if not too long…
          input                            // Just return original string.
      ;
      

      看到这个code run live at IdeOne.com.

      abcdefghi…

      Java 流

      Java Streams 工具使这变得有趣,从 Java 9 及更高版本开始。有趣,但可能不是最好的方法。

      我们使用code points 而不是char 值。 char 类型是旧的,并且仅限于 a subset of 所有可能的 Unicode 字符。

      String input = "abcdefghijkl" ;
      int limit = 10 ;
      String output =
              input
                      .codePoints()
                      .limit( limit )
                      .collect(                                    // Collect the results of processing each code point.
                              StringBuilder::new,                  // Supplier<R> supplier
                              StringBuilder::appendCodePoint,      // ObjIntConsumer<R> accumulator
                              StringBuilder::append                // BiConsumer<R,​R> combiner
                      )
                      .toString()
              ;
      

      如果我们截断了多余的字符,请将最后一个字符替换为 ellipsis

      if ( input.length () > limit )
      {
          output = output.substring ( 0 , output.length () - 1 ) + "…";
      }
      

      如果我能想出一种方法将流线与“如果超出限制,则省略”部分放在一起。

      【讨论】:

        【解决方案9】:
        str==null ? str : str.substring(0, Math.min(str.length(), 10))
        

        或者,

        str==null ? "" : str.substring(0, Math.min(str.length(), 10))
        

        适用于 null。

        【讨论】:

        • 但请注意,如果您不期待null,您不应该这样做。处理(意外)空值的最佳方法是让 NPE 发生(尽快),然后使用错误报告追踪并消除意外null 的原因。如果您在不了解来源的情况下“防御性地”测试空值,最终可能会掩盖重大错误的原因。
        【解决方案10】:

        这个问题是在 Java 上提出的,但它是在 2014 年提出的。
        如果你现在使用 Kotlin,它很简单:

        yourString.take(10)
        

        返回一个包含此字符串前 n 个字符的字符串,如果此字符串较短,则返回整个字符串。

        Documentation

        【讨论】:

          【解决方案11】:

          // 这就是用 .. 缩短字符串长度的方法 // 将以下方法添加到您的类中

          private String abbreviate(String s){
            if(s.length() <= 10) return s;
            return s.substring(0, 8) + ".." ;
          }
          

          【讨论】:

          猜你喜欢
          • 2016-07-07
          • 2014-01-17
          • 1970-01-01
          • 1970-01-01
          • 2023-03-20
          • 1970-01-01
          • 2013-11-25
          • 1970-01-01
          相关资源
          最近更新 更多