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