精选技术技术2026-09-16 01:32:59(编辑于 2026-09-16 01:33:17)

正则表达式

一、正则是什么

一句话:用"符号"来描述"字符串长什么样"的规则。给一个模式,拿去匹配输入的字符串。

"^1\\d{10}$"  ← 规则(模式)
   ↓ 匹配
"13812345678" → 命中 ✅
"123"         → 不命中 ❌

二、三大积木

正则 = 锚点 + 字符 + 量词,反复组合。

① 锚点(管位置)

符号 意思
^ 字符串开头
$ 字符串结尾

② 字符(管这个位置是什么)

写法 意思 例子
1 字面量 只匹配字符 1
[0-9] 字符集,1 个字符,范围 0~9 [38] 匹配 3 或 8
\d 任意一位数字(= [0-9])
\w 字母/数字/下划线(= [a-zA-Z0-9_])
. 任意一个字符(有特殊含义,要匹配字面量点需写 \.)
- _ @ 普通字符按字面匹配

③ 量词(管前面那个出现几次)

写法 意思
{8} 恰好 8 次
{4,32} 4~32 次
+ 至少 1 次
* 0 次或多次
? 0 次或 1 次
| 或(并列选项)

核心思想:不会读就先拆——看到 | 就数"几个并列选项",看到 (...) 就圈出来"这是一组"。

三、项目里的 4 个正则(逐个拆)

① 验证码:^[a-zA-Z\d]{6}$

^            开头
 [a-zA-Z\d]  一个"字母或数字"
       {6}   重复 6 次
            $ 结尾

→ 恰好 6 位字母/数字。Ab3f9z ✅,12345 ❌

② 密码:^\w{4,32}$

\w = 字母/数字/下划线,{4,32} = 4~32 位。

→ 4~32 位字母、数字或下划线。pass_123 ✅,123 ❌

③ 手机号:^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\d{8}$

分段拆解:

^1                       开头是 1
  ( 选一个 )             这组括号 = 从下列选项里选一个
     [38][0-9]           第二位 3/8,第三位 0~9
     | 4[579]            第二位 4,第三位 5/7/9(145/147/149)
     | 5[0-3,5-9]        第二位 5,第三位 0~3 或 5~9(150~153、155~159)
     | 6[6]              166
     | 7[0135678]        170/171/173/175/176/177/178
     | 9[89]             198/199
  \d{8}                  最后 8 位数字
$                        结尾

→ 1 + 合规 3 位号段 + 8 位数字 = 11 位手机号(号码段规则编码在正则里)

注意:5[0-3,5-9] 里的逗号是作者写的冗余([0-3] [5-9] 已覆盖,逗号本身不是数字匹配不到),不影响正确性。

④ 邮箱:^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$

^[a-zA-Z0-9_-]+       用户名:至少 1 个 字母/数字/下划线/减号
@                     必须有 @
[a-zA-Z0-9_-]+        域名主体:至少 1 个
(\. [a-zA-Z0-9_-]+)+  这整组重复 1 次或多次:
                         \.           匹配字面量点(必须转义!)
                         [a-zA-Z0-9_-]+  点后的部分
$                    结尾

→ 用户名@域名.顶级域名,支持多级域名((...)+ 允许 @mail.xxx.com.cn)

坑:. 是"任意字符",匹配字面量点必须写 \.,否则 @qqXcom 也会通过。

四、Java 里怎么用

String.matches(regex) 是整串完全匹配(自动带开头结尾要求),所以 ^...$ 在 Java 里可省,但写全更明确、可移植到别的语言:

"pass_123".matches("^\\w{4,32}$");   // true
"abc".matches("^\\w{4,32}$");        // false

项目实际用法(RegexUtils.mismatch,反向命名):

public static boolean isPhoneInvalid(String phone){
    return mismatch(phone, RegexPatterns.PHONE_REGEX);
}
// 调用处:返回 true = 不匹配 = 手机号无效
if (RegexUtils.isPhoneInvalid(phone)) {
    return Result.fail("手机号格式错误");
}

五、速记

  • \d 数字、\w 字母数字下划线、. 任意字符、\. 字面量点
  • + 至少1次、* 0次起、{n,m} 精确范围、| 或、(...) 一组
  • 不会读就分段拆:先找锚点,再找 | 列选项,再圈 (...) 组
  • Java 的 matches 整串匹配,^...$ 写全更明确