在 Java 正则表达式里,[] 看起来只是一个简单符号,但它几乎决定了“这个位置到底允许出现哪些字符”。很多入门问题其实都出在这里:字符范围怎么写、排除字符怎么写、哪些符号进了中括号后会失去特殊含义,以及什么时候还得继续转义。本文按这些高频疑问拆开讲,并结合一个 Java 校验示例说明为什么整串判断时应优先考虑 matches(),这样读完就能直接判断自己的写法是否准确。
中括号的核心作用:定义可匹配字符集
在正则表达式中,中括号 [] 表示一个字符集,也就是“当前位置可以匹配括号中的任意一个字符”。它匹配的是单个字符,不是整个单词或字符串。

匹配指定字符
最基础的写法就是把可接受的字符直接列出来:
[abc]:匹配a、b或c中任意一个字符。
这种写法适合候选值很少、规则非常明确的场景,比如只允许若干个固定标识字符。
用连字符表示范围
如果候选字符是连续区间,就可以用 - 表示范围,写法会更紧凑:

[a-z]:匹配所有小写字母[A-Z]:匹配所有大写字母[0-9]:匹配任意数字
这类范围写法是字符集最常见的用法之一,尤其适合账号、编号、标识符之类的输入校验。
范围组合与排除写法怎么理解
字符集不仅能写单一范围,还能把多组范围和普通字符拼在一起,用一个表达式覆盖更完整的输入规则。
多个范围可以直接组合
例如:
[a-zA-Z]:匹配任意字母,不区分大小写范围[a-zA-Z0-9]:匹配字母或数字[a-zA-Z0-9_]:匹配字母、数字或下划线
这种组合方式非常实用,因为它直接表达了“允许哪些字符出现”,可读性也比一连串分支更好。
在开头加 ^ 表示排除
如果想表达“除了这些字符都可以”,可以在左中括号后紧跟一个 ^:
[^abc]:匹配除a、b、c之外的任意一个字符[^0-9]:匹配任何非数字字符
这里要注意,^ 只有放在字符集开头附近时才表示“排除”。如果位置不同,它就未必承担这个含义了。
字符集里的特殊字符和转义规则
很多人学习正则时容易把“字符集内部”和“字符集外部”的规则混在一起。实际上,字符进入 [] 之后,语义会简化不少。
不少特殊字符在中括号里会失去特殊含义
在字符集内部,很多原本有特殊意义的字符,例如 .、*、+、,通常都退化为普通字符,直接表示它们自己。
但这不意味着字符集里完全没有规则例外。至少下面几个符号仍然要特别留意:
^:在特定位置表示排除-:在两个字符之间时常用于表示范围:仍然承担转义作用
需要转义的字符有哪些
如果想在字符集中匹配这些字符本身:]、-、^ 或 ,通常需要使用反斜杠转义。
例如:
[]]:用于匹配一个右中括号]
这种写法初看有些绕,因为一个 ] 要作为字符内容出现,另一个 ] 又要承担结束字符集的作用。实际使用时,只要记住字符集里的 ]、-、^、 需要额外关注,就能少掉不少语法错误。
Java 示例:校验字符串只包含小写字母和数字
下面看一个更贴近实际使用的例子:判断一个字符串是否只由小写字母或数字组成。
![Java 正则里的中括号怎么用:字符集、范围、排除与示例详解_wishdown.com 展示正则 ^[a-z0-9]+$ 在 Java 校验中的组成部分,以及 find() 与 matches() 的适用区别。](https://img.wishdown.com/upload/news/202608248ca112f9bc1eaeb396378e7a57bb12b4.webp)
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class RegexExample {
public static void main(String[] args) {
String pattern = "^[a-z0-9]+$";
Pattern r = Pattern.compile(pattern);
// 测试字符串
String testString1 = "hello123";
String testString2 = "Hello123";
// 创建 matcher 对象
Matcher m1 = r.matcher(testString1);
Matcher m2 = r.matcher(testString2);
if (m1.find()) {
System.out.println("testString1: " + testString1 + " 匹配");
} else {
System.out.println("testString1: " + testString1 + " 不匹配");
}
if (m2.find()) {
System.out.println("testString2: " + testString2 + " 匹配");
} else {
System.out.println("testString2: " + testString2 + " 不匹配");
}
}
}
这段代码里的正则是 ^[a-z0-9]+$,它可以拆成几部分理解:
^:匹配字符串开头[a-z0-9]:每一位只能是小写字母或数字+:前面的字符集至少出现一次$:匹配字符串结尾
合起来的意思就是:整个字符串从头到尾只能由小写字母或数字组成,并且长度至少为 1。
因此:
hello123符合规则Hello123因为包含大写字母H,不符合规则
为什么这里更适合用 matches()
原示例使用的是 find()。这个方法的含义是查找是否存在一个能匹配的子串,而不是强制整个字符串完整匹配。
如果你的目标是校验“整个输入值是否满足规则”,更合适的方法是 matches()。因为这个场景关注的是整串合法性,而不是局部是否命中。
也就是说,这个例子虽然通过 ^ 和 $ 已经把边界写得很完整,但从语义上看,matches() 仍然比 find() 更贴近需求,也更不容易让后续维护者误解代码意图。
怎么快速判断 [] 写得对不对
如果把 Java 正则里的中括号用一句话概括,它就是“定义某一位允许出现哪些字符”的工具。写法上最常见的几类分别是:直接列字符、使用范围、组合多个范围,以及用 [^...] 表示排除。
实际编写时,可以重点检查这几件事:
- 当前需求匹配的是一个字符,还是整个字符串
-是想表示范围,还是要匹配它本身^是放在字符集开头表示排除,还是只是普通字符- 是否需要对
]、-、^、做转义 - 在 Java 代码里,整串校验是否应该使用
matches()而不是find()
把这些点理顺之后,像 [a-z]、[a-zA-Z0-9]、[^0-9] 这类字符集写法基本就不会再混淆。对于账号、表单、标识符和基础文本校验来说,这也是最常用、最值得先掌握的一组正则能力。







