在Java开发中,经常会遇到需要将长字符串按照固定长度分组,并且在每组之间插入空格的场景,比如格式化银行卡号、手机号、身份证号等展示内容,让内容更易读。下面介绍几种常见的实现方式,开发者可以根据实际需求选择使用。

方案一:使用循环截取实现
这种方式逻辑比较直观,通过循环每次截取固定长度的子串,拼接时加入空格即可,适合所有Java版本,兼容性最好。
public class StringGroupUtil {
/**
* 按固定长度分组字符串并插入空格
* @param origin 原始字符串
* @param groupSize 每组长度
* @return 分组后的字符串
*/
public static String groupByLength(String origin, int groupSize) {
if (origin == null || origin.isEmpty() || groupSize <= 0) {
return origin;
}
StringBuilder result = new StringBuilder();
int length = origin.length();
for (int i = 0; i < length; i += groupSize) {
// 截取当前组的子串,避免越界
int end = Math.min(i + groupSize, length);
result.append(origin.substring(i, end));
// 不是最后一组时添加空格
if (end < length) {
result.append(" ");
}
}
return result.toString();
}
public static void main(String[] args) {
String cardNo = "6222021234567890123";
String grouped = groupByLength(cardNo, 4);
System.out.println(grouped); // 输出:6222 0212 3456 7890 123
}
}
方案二:使用正则表达式实现
利用正则表达式的零宽度正预测先行断言,可以在每固定长度的位置插入空格,代码更简洁,但是正则匹配的性能会比循环稍低。
public class StringGroupUtil {
/**
* 用正则按固定长度分组字符串并插入空格
* @param origin 原始字符串
* @param groupSize 每组长度
* @return 分组后的字符串
*/
public static String groupByRegex(String origin, int groupSize) {
if (origin == null || origin.isEmpty() || groupSize <= 0) {
return origin;
}
// 正则含义:匹配后面跟groupSize个非换行字符的位置,插入空格
String regex = "(?<=\G.{" + groupSize + "})";
return origin.replaceAll(regex, " ");
}
public static void main(String[] args) {
String phone = "13812345678";
String grouped = groupByRegex(phone, 3);
System.out.println(grouped); // 输出:138 123 456 78
}
}
两种方案对比
我们可以通过下面的表格对比两种实现方式的特点,方便选择:
| 实现方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 循环截取 | 逻辑清晰,性能好,兼容性强 | 代码量稍多 | 对性能要求高、需要兼容低版本Java的场景 |
| 正则表达式 | 代码简洁,一行即可实现 | 正则匹配性能稍低,可读性稍差 | 代码简洁度要求高、字符串长度较短的场景 |
注意事项
- 如果原始字符串中包含空格,需要先调用
replaceAll("\s+", "")去除空格再处理,避免分组结果不符合预期。 - 分组长度需要大于0,否则方法会直接返回原始字符串,避免无意义的空分组。
- 如果原始字符串长度不是分组长度的整数倍,最后一组的长度会小于分组长度,属于正常情况,不需要额外处理。
实际开发中如果分组规则固定,比如固定每4位插入空格,也可以直接写死分组长度,不需要每次传入参数,减少不必要的参数校验逻辑。