regionMatches()用于比较两字符串指定区域是否相等,支持忽略大小写:true仅对ASCII字母做toLowerCase等价判断,非拉丁字符(如中文)不受影响;需确保偏移和长度合法,否则抛IndexOutOfBoundsException。

regionMatches() 忽略大小写的参数含义要搞清
String.regionMatches() 的第三个重载方法支持忽略大小写比较,但很多人误以为只要传 true 就万事大吉。实际签名是:boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)。关键点在于:它**只对参与比较的子串做忽略大小写处理,不改变原字符串,也不做 Unicode 大小写折叠(比如德语 ß、土耳其语 I/i)**,仅基于 ASCII 范围内简单的 Character.toLowerCase() 等价判断。
使用时必须确保:
-
toffset和ooffset都在各自字符串合法索引范围内(0 ≤ offset ≤ str.length(),且offset + len ≤ str.length()) -
len不能为负;若为 0,直接返回true(空片段恒等) - 如果任一偏移越界或长度超限,方法抛
IndexOutOfBoundsException,不是返回false
比较长字符串中间片段的典型写法
假设你有两个长字符串 textA 和 textB,想比对它们从第 100 位开始、长度为 50 的子串是否相等(忽略大小写):
boolean match = textA.regionMatches(true, 100, textB, 100, 50);
注意:这里没有调用 substring(),避免额外创建子串对象,内存友好。但如果 textA 或 textB 长度不足 150,就会炸——所以生产环境建议先校验长度:
安全写法应包含前置检查:
- 用
Math.min(textA.length(), textB.length()) >= 100 + 50判断是否够长 - 或者捕获
IndexOutOfBoundsException(不推荐,异常开销大) - 若偏移量来自用户输入或配置,务必做范围 clamp,例如
int safeOffset = Math.max(0, Math.min(100, textA.length()))
和 equalsIgnoreCase() + substring() 对比有什么坑
有人图省事写成:textA.substring(100, 150).equalsIgnoreCase(textB.substring(100, 150))。这看似等价,但有三个硬伤:
第一,substring() 在 Java 7u6 之后虽不再共享底层数组,但仍会复制字符数组,对超长字符串(如 1MB 文本)触发明显 GC 压力;regionMatches() 是纯指针偏移+逐字符比较,零拷贝。
第二,如果 textA.length() == 120,substring(100, 150) 直接抛 StringIndexOutOfBoundsException;而 regionMatches() 的越界检查更早、更明确。
第三,equalsIgnoreCase() 内部其实也调用了类似逻辑,但多了一层对象创建和方法分派开销。
非 ASCII 字符(如中文、日文)会影响结果吗
不影响。因为 regionMatches(true, ...) 的“忽略大小写”**仅作用于能被 Character.isLowerCase()/isUpperCase() 识别的字符**,也就是拉丁字母 A–Z/a–z、部分带变音符号的字母(如 À/à),而中文、日文平假名/片假名、emoji 等本身无大小写概念,该标志对其完全透明——它们按原始 Unicode 码点逐字符比对。
也就是说:对纯中文字符串调用 regionMatches(true, ...) 和 regionMatches(false, ...) 效果完全一样;但混有英文时,英文部分才真正享受忽略大小写待遇。
如果你需要真正的国际化大小写折叠(比如匹配德语 "STRASSE" 和 "straße"),regionMatches() 不行,得用 java.text.Normalizer + Collator,那是另一套机制了。
真正容易被忽略的是越界检查和非拉丁字符的“伪忽略”行为——前者导致线上崩溃,后者导致测试用例侥幸通过、上线后偶发不匹配。










