应根据需求选择:只需从某位置截取到末尾用 substring(int beginindex),需指定起止范围则用 substring(int beginindex, int endindex),注意 endindex 是不包含的结束索引,非长度,且须满足 0 ≤ beginindex ≤ endindex ≤ str.length。

substring() 的两个重载版本怎么选
Java 中 substring() 是最常用的字符串截取方法,但它有两个重载:
substring(int beginIndex) 和 substring(int beginIndex, int endIndex)。
关键区别在于:第二个参数是「结束索引(不包含)」,不是长度。很多人误以为 substring(2, 5) 是“取 5 个字符”,结果只拿到下标 2、3、4 三个字符。
常见错误现象:StringIndexOutOfBoundsException,尤其当 endIndex > str.length() 或 beginIndex 时抛出。
- 安全写法:截取前先校验边界,例如
Math.min(endIndex, str.length()) - 若只需从某位置到末尾,用单参数版更简洁,比如
str.substring(3) - 注意:两个版本都返回新字符串,原字符串不变(String 不可变)
replaceFirst() 和 replaceAll() 能不能当“条件截取”用
它们本质是正则替换,不是截取函数,但常被误用于“去掉开头/结尾某段”。比如想删掉前缀 "prefix_",有人写 s.replaceFirst("^prefix_", "") —— 这能工作,但有隐患:
-
replaceFirst()参数是正则,"."、"+"、"*"等会特殊解释,没转义就出错 - 性能比
startsWith()+substring()差,尤其短字符串场景 - 真正需要“按模式切分”时,应优先考虑
split()或Pattern+Matcher
推荐替代方案:s.startsWith("prefix_") ? s.substring(7) : s,语义清晰、零正则开销、空安全好控制。
用 split() 截取要注意的三个边界情况
split(String regex) 返回 String[],看似方便,但默认会丢弃末尾空串,且对空输入、全匹配、limit 参数敏感。
立即学习“Java免费学习笔记(深入)”;
- 空字符串
"".split(",")返回长度为 1 的数组:[""],不是空数组 -
"a,,b".split(",")得到["a", "", "b"];但"a,,b,".split(",")只得["a", "", "b"](末尾空串被丢) - 要保留末尾空串,必须传
-1作 limit:s.split(",", -1) - 如果分隔符是正则元字符(如
"."),必须转义:s.split("\.")
Java 11+ 新增的 strip() 和 takeWhile() 适合什么截取场景
strip()、stripLeading()、stripTrailing() 专用于去除首尾空白(Unicode 意义上的 whitespace),比 trim() 更准——它支持 Unicode 2.0+ 的所有空白字符(如 、 )。
而 takeWhile(Predicate<Character>) 和 dropWhile(Predicate<Character>) 是真正的“按条件截取”:
-
"123abc".takeWhile(Character::isDigit)→"123" -
"123abc".dropWhile(Character::isDigit)→"abc" - 注意:它们按 code point 处理,对代理对(surrogate pairs)安全;但一旦遇到不满足条件的字符就停止,不回溯
- 不适用于复杂逻辑(如“跳过前两个数字再取”),此时还是
for+charAt()更可控
这些方法在 JDK 11+ 才可用,旧项目升级前需确认兼容性;另外它们都返回新字符串,和所有 String 方法一样,不修改原对象。










