Jakarta @Pattern注解正则表达式指定最大长度时匹配失败
解决Jakarta @Pattern注解中带最大长度限制的正则匹配问题
我在Spring Boot 3.2.3(Java 17、Gradle 7.5.1)环境下遇到一个正则匹配问题:
- 不带最大长度限制的正则在@Pattern注解中正常工作:
@Pattern(regexp = "^(?=.*\\d)(.{8,})$") private String str;
- 但添加最大长度30的限制后,无论字符串是否合法都无法匹配:
@Pattern(regexp = "^(?=.*\\d)(.{8,30})$") private String str;
奇怪的是,这个带最大长度的正则用String.matches()测试时完全正常,第三方正则测试工具也验证通过:
String regex = "^(?=.*\\d)(.{8,30})$"; String validString= "12345678"; // 8个字符 assertTrue(validString.matches(regex)); String invalidString = "123456789012345678901234567890A"; // 31个字符 assertFalse(invalidString.matches(regex));
可行修改方案
方案1:拆分长度断言与内容匹配
将总长度限制单独放在一个环视断言中,确保整体逻辑清晰,避免注解解析冲突:
@Pattern(regexp = "^(?=.*\\d)(?=.{8,30}$).*$") private String str;
方案2:明确匹配所有字符类型
用[\s\S]替代.(可匹配包括换行在内的所有字符,若无需匹配换行,.{8,30}也可),调整结构后适配注解解析逻辑:
@Pattern(regexp = "^(?=.*\\d)[\\s\\S]{8,30}$") private String str;
问题原因
Jakarta Validation的@Pattern注解实现中,对(.{8,30})这类紧跟在断言后的长度匹配组可能存在特殊解析逻辑,导致规则失效。通过拆分断言与长度限制、明确字符匹配范围,可以规避该解析异常。
内容的提问来源于stack exchange,提问作者flobbe9
相关产品推荐
相关产品推荐

