Java 删除字符串的最后一个字符

1,039 阅读2分钟

近期在写 Java 程序时,遇到大量需要删除字符串最后一个字符的逻辑,特意书写该篇文章来讲解各种截取方式。

需要注意的是我们演示代码使用的是 Java 8

String.substring()

在 String 类中自带了 substring() 方法。

为了删除字符串的最后一个字符,我们必须使用两个参数:0 作为起始索引,以及倒数第二个字符的索引。我们可以通过调用 String 的 length() - 1 方法来实现这一点。

这种操作方式不是空安全的,如果我们使用空字符串,则会失败并抛出 java.lang.StringIndexOutOfBoundsException: Range [0, -1) out of bounds for length 0 错误信息。

为了解决 null 和空字符串的问题,我们可以将该方法包装:

public static String removeLastChar(String s) {
    return Optional.ofNullable(s)
      .filter(str -> str.length() != 0)
      .map(str -> str.substring(0, str.length() - 1))
      .orElse(s);
}

StringUtils.substring()

使用 Apache Commons Lang3 库中的 StringUtils 类,它提供了大量的字符串操作方法。其中之一是 null-safe substring() 方法,用于处理异常。

添加依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>${lang3.version}</version>
</dependency>

${lang3.version} 可以通过在 maven 中央仓库获取。

StringUtils.substring() 需要三个参数:

  • 指定的字符串
  • 第一个字符的索引(由于我们是截取最后一个字符那么在这里索引始终是 0)
  • 倒数第二个字符的索引(也就是字符串的 str.length() - 1)
String str = "Hello Word";
StringUtils.substring(str, 0, str.length() - 1);

但是该方法还是非安全的,因为在底层代码中只是处理 null 相关处理。

public static String substring(final String str, int start, int end) {
        if (str == null) {
            return null;
        }

        // handle negatives
        if (end < 0) {
            end = str.length() + end; // remember end is negative
        }
        if (start < 0) {
            start = str.length() + start; // remember start is negative
        }

        // check length next
        if (end > str.length()) {
            end = str.length();
        }

        // if start is greater than end, return ""
        if (start > end) {
            return EMPTY;
        }

        if (start < 0) {
            start = 0;
        }
        if (end < 0) {
            end = 0;
        }

        return str.substring(start, end);
    }

StringUtils.chop()

StringUtils 类提供了 chop() 方法,该方法适用于所有边缘场景:empty 字符串null 字符串

非常容易使用,并且只需要一个参数:字符串。它的唯一目的是删除最后一个字符:

StringUtils.chop(str);

使用正则表达式

还可以通过利用正则表达式从字符串中删除最后一个字符(或任意数量的字符)。

我们可以使用 String 类本身的 replaceAll() 方法,该方法有两个参数:正则表达式和原始字符串:

str.replaceAll(".$", "");

在 String 上调用方法,所以该操作不是 null-safe 的。

为了使逻辑对用户更加友好,我们可以将其包装:

public static String removeLastCharRegex(String str) {
    return (str == null) ? null : str.replaceAll(".$", "");
}

如果字符串以换行符结尾,该方法将失败,因为 . 在正则表达式中匹配除行终止符之外的任何字符。

我们改造一下,最终的的效果为:

public static String removeLastCharRegexOptional(String s) {
    return Optional.ofNullable(s)
      .map(str -> str.replaceAll(".$", ""))
      .orElse(s);
}