在Java开发中,经常需要处理字符串中特定位置的数字范围校验需求,比如校验手机号中间四位是否在指定区间,或者校验订单编号中某几位数字是否符合业务规定的数值范围。这类需求如果处理不当很容易出现边界判断错误或者性能问题,下面介绍两种常用的实现方案。

方案一:手动截取转换校验
这种方案的核心思路是先截取字符串中目标位置的子串,将其转换为数值类型,再判断数值是否在指定范围内。适合需要灵活处理复杂范围逻辑的场景。
实现步骤
- 先校验原字符串的长度是否足够,避免截取时出现索引越界
- 使用
substring方法截取目标位置的数字子串 - 将截取到的子串转换为整数类型,同时处理转换异常的情况
- 判断转换后的数值是否在目标范围内
代码示例
public class StringNumberCheck {
/**
* 手动校验字符串中特定位置的数字范围
* @param source 原字符串
* @param start 数字起始索引(包含)
* @param end 数字结束索引(不包含)
* @param min 范围最小值
* @param max 范围最大值
* @return 校验是否通过
*/
public static boolean manualCheck(String source, int start, int end, int min, int max) {
// 先校验原字符串长度和索引合法性
if (source == null || source.length() < end || start < 0 || start >= end) {
return false;
}
String numStr = source.substring(start, end);
// 校验截取到的子串是否全是数字
if (!numStr.matches("\d+")) {
return false;
}
try {
int num = Integer.parseInt(numStr);
return num >= min && num <= max;
} catch (NumberFormatException e) {
// 数字超出int范围的情况
return false;
}
}
public static void main(String[] args) {
// 校验字符串"ORDER202305001"中第5到9位的数字是否在2023到2024之间
String testStr = "ORDER202305001";
boolean result = manualCheck(testStr, 5, 9, 2023, 2024);
System.out.println("手动校验结果:" + result);
}
}
方案二:正则表达式校验
正则表达式方案适合固定格式的范围校验场景,通过编写匹配特定位置数字范围的正则规则,直接对字符串进行匹配判断,代码更简洁。
正则规则编写思路
如果目标位置的数字范围是固定的,比如要匹配100到200之间的三位数,可以拆分规则:100-199匹配1[0-9]{2},200匹配200,组合起来就是1[0-9]{2}|200。再结合原字符串的其他格式规则,拼接成完整的正则表达式。
代码示例
public class RegexNumberCheck {
/**
* 正则校验字符串中特定位置的数字范围
* @param source 原字符串
* @param regex 完整的正则表达式,包含目标位置数字范围规则
* @return 校验是否通过
*/
public static boolean regexCheck(String source, String regex) {
if (source == null) {
return false;
}
return source.matches(regex);
}
public static void main(String[] args) {
// 校验字符串以ORDER开头,接着是100到200之间的四位数字,最后是三位任意数字
// 其中第5到9位(四位数字)的范围是1000到1200,正则规则拆分:1000-1199是1[0-1][0-9]{2},1200是1200
String regex = "ORDER(1[0-1][0-9]{2}|1200)\d{3}";
String testStr1 = "ORDER11500001";
String testStr2 = "ORDER12000001";
String testStr3 = "ORDER13000001";
System.out.println("正则校验testStr1结果:" + regexCheck(testStr1, regex));
System.out.println("正则校验testStr2结果:" + regexCheck(testStr2, regex));
System.out.println("正则校验testStr3结果:" + regexCheck(testStr3, regex));
}
}
两种方案对比
| 对比维度 | 手动截取转换方案 | 正则表达式方案 |
|---|---|---|
| 适用场景 | 范围逻辑复杂、需要动态传入范围参数的场景 | 范围固定、字符串格式固定的场景 |
| 代码可读性 | 逻辑清晰,容易理解和修改 | 正则规则复杂时可读性较差 |
| 性能 | 多次方法调用,性能稍低 | 单次匹配,性能更高 |
| 灵活性 | 可以灵活处理各种异常和边界情况 | 规则固定,修改需要重新编写正则 |
注意事项
- 使用手动截取方案时,一定要先校验字符串长度和索引的合法性,避免出现
StringIndexOutOfBoundsException异常 - 如果目标位置的数字可能超过int类型的范围,需要将转换类型改为long,使用
Long.parseLong方法 - 编写正则表达式时,要注意数字范围的拆分逻辑,避免出现范围遗漏或者覆盖错误的情况
- 如果字符串中有特殊字符,需要在正则中做对应的转义处理,比如
.需要转义为\.
开发者可以根据实际的业务场景选择合适的校验方案,如果是简单的固定范围校验,优先选择正则表达式方案,效率更高;如果是动态范围或者复杂逻辑校验,手动截取转换方案更合适。