正则表达式入门:10 个日常工作最常用的模式
2026-08-06
很多人对正则表达式的第一印象是”一行看不懂的天书”:一堆斜杠、方括号、花括号挤在一起,复制过来能用就行,出了 bug 却不知道从哪改起。其实正则的核心概念就那么几个——字符类、量词、分组、锚点,掌握之后你会发现日常 80% 的匹配需求只需要很短的模式就能解决。这篇文章不讲大而全的语法手册,而是挑出实际工作里最高频的 10 个模式,逐个符号拆开解释,读完你就能自己写、自己改,而不是只能抄。
正则到底是什么
正则表达式(Regular Expression,常简写 regex)是一种描述”字符串长什么样”的小型语言。你给它一个模式,它就能在一段文本里回答两类问题:这段文本符不符合这个格式(校验),以及把符合这个格式的部分找出来(提取)。几乎所有主流语言都内置了正则引擎,编辑器、命令行的 grep、日志分析工具也都支持它。
看一个最小的例子:\d{3}-\d{4} 能匹配 010-1234 这样的字符串。其中 \d 表示”任意一个数字”,{3} 表示”前面的东西重复 3 次”,- 就是字面意义的短横线。正则的所有模式都是这样由小零件拼起来的,看懂零件,就看懂了整体。
模式 1:邮箱地址
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
逐段拆解:^ 和 $ 是锚点,分别表示”字符串开头”和”结尾”,加上它们表示整段文本必须完全符合模式,而不是只包含一段邮箱。[a-zA-Z0-9._%+-] 是一个字符类,方括号里列出的字符任意出现其中一个就算匹配;后面的 + 表示”至少一次”。中间的 @ 是字面字符。\. 中的反斜杠用来转义——点号在正则里本来表示”任意字符”,转义后才表示真正的英文句点。{2,} 表示顶级域名至少两个字母。
需要说明的是,完全符合 RFC 5322 规范的邮箱正则有上千个字符,没人真的那么写。上面这个模式覆盖了正常业务里 99% 的邮箱,做表单校验足够用。如果你只是想快速验证一个邮箱格式而不想写代码,也可以直接用在线的邮箱校验工具。
模式 2:URL
https?://[\w-]+(\.[\w-]+)+[\w\-.,@?^=%&:/~+#]*
s? 里的问号表示前一个字符出现 0 次或 1 次,所以 http 和 https 都能匹配。\w 等价于 [a-zA-Z0-9_],即字母、数字和下划线。(\.[\w-]+)+ 是一个分组,匹配 .com、.example.co 这类以点号分隔的域名段,整个分组用 + 表示至少出现一次。最后一段方括号里罗列了 URL 路径和查询串里常见的合法字符,用 * 表示可以出现任意多次(包括零次)。
这个模式适合从文本里提取 URL。如果你要做严格的 URL 合法性校验,建议在代码里用语言自带的 URL 解析器,正则只做粗筛。
模式 3:手机号(中国大陆)
^1[3-9]\d{9}$
这是国内表单里最常用的模式之一,而且很好读:手机号以 1 开头,第二位是 3 到 9 之间的数字,后面再跟 9 个数字,总共 11 位。[3-9] 这种短横线连接的范围写法是字符类的核心技巧,a-z、0-9 同理。
如果你的系统面向国际用户,手机号就没有通用正则可言了——各国位数和规则差异巨大,这时应该用专门的号码解析库而不是正则。
模式 4:日期 YYYY-MM-DD
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
这个模式值得细看,因为它展示了分组加竖线的写法。圆括号 (...) 把多个选项括成一组,竖线 | 表示”或”。月份部分 (0[1-9]|1[0-2]) 只允许 01–09 和 10–12,排除了 00、13 这样的非法值;日期部分同理,允许 01–31。
注意这个正则只能保证格式合法,不能保证日期真实存在——2026-02-31 依然能匹配,因为 2 月没有 31 天。要校验真实日期,必须结合代码逻辑。这正是”正则做格式校验、程序做语义校验”这条原则的典型例子。
模式 5:提取数字(含小数和负数)
-?\d+(\.\d+)?
开头的 -? 表示可选的负号。\d+ 匹配整数部分,(\.\d+)? 整体是可选的小数部分:分组里的 \. 是小数点,\d+ 是小数位数,外层问号表示”小数部分可以没有”。所以它能同时匹配 42、-7 和 3.14。
这是日志分析和数据清洗里用得最多的模式之一:配合全局匹配标志(JavaScript 里的 g 标志),可以一次把一段文本里的所有数字全部抓出来。
模式 6:去除首尾空白
^\s+|\s+$
\s 表示任意空白字符,包括空格、制表符、换行。这个模式配合替换操作使用:把匹配到的内容替换成空字符串,效果等同于各语言的 trim()。中间的 | 让两个分支分别吃掉开头和结尾的空白,一次替换全搞定。
如果还想把文本中间的多个连续空格压缩成一个,可以再加一步,把 \s{2,} 替换成单个空格——{2,} 表示”至少两次”。
模式 7:匹配引号内的字符串
"([^"\\]|\\.)*"
处理 CSV、解析简单配置时经常需要把双引号包住的内容提取出来。这个模式的骨架是 "...",难点在中间:[^"\\] 用否定字符类匹配”既不是引号也不是反斜杠的字符”,\\. 则匹配转义序列(比如 \"、\\),两者用竖线组成一个分组,再整体重复任意次。这样即使字符串内部有 \" 也不会让匹配提前结束。
模式 8:IPv4 地址
\b((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\b
这个模式看起来吓人,结构其实很简单:它把”一个合法的 0–255 数字段”写成了 (25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d) 这个分支组——250 到 255、200 到 249、100 到 199、其余 0 到 99,四种情况合起来恰好覆盖 0–255,排除了 999.1.1.1 这类假地址。前三段后面各跟一个点号,用 {3} 重复,最后一段不带点号。\b 是单词边界,防止从更长的数字串中间切出一段来匹配。
日常排障时如果只想要个粗略模式,\b(?:\d{1,3}\.){3}\d{1,3}\b 也够用——上面这个严格版适合写进校验逻辑。
模式 9:匹配中文
[一-龥]+
方括号里用 Unicode 码位范围 [一-龥](即 \u4e00 到 \u9fff)覆盖了绝大多数常用汉字,配合 + 可以匹配连续的中文字符串。在 JavaScript 里也可以写成 [\u4e00-\u9fff]+,两种写法等价。常见用途是校验”姓名必须是中文”或者从混排文本里提取中文部分。需要注意这个范围不含中文标点,如果要去掉中文逗号句号,得另外列出。
模式 10:匹配 HTML 标签
<([a-z][a-z0-9]*)\b[^>]*>(.*?)</\1>
最后这个模式引入了两个高级零件。([^>]* 里的否定字符类匹配属性部分(任何不是 > 的字符);(.*?) 里的 ? 让量词变成非贪婪模式,匹配到最近的闭合标签就停;\1 是反向引用,表示”和第 1 个分组捕获到的内容相同的文本”,保证开闭合标签同名——<div>...</div> 能匹配,<div>...</span> 不能。
顺便说一句业界共识:正则不适合解析完整的 HTML(HTML 不是正则语言),但用来抓取结构简单、格式固定的片段,它依然是最快的方案。
贪婪与非贪婪:最容易踩的坑
量词(*、+、{m,n})默认是贪婪的:能匹配多少就匹配多少。经典例子是用 <.+> 去匹配 <b>加粗</b> 普通文字 <i>斜体</i>,你以为会匹配到 <b>,实际却从第一个 < 一路吃到行尾最后一个 >,把整行都吞了——因为 .+ 先吃到不能再吃,引擎再回退找最后的 >。
在量词后面加一个 ? 就变成非贪婪(也叫懒惰):能少匹配就少匹配。把模式改成 <.+?>,就会得到 <b>、</b>、<i>、</i> 四个独立的短匹配。经验法则是:当你要匹配”到某个结束符为止”的内容时,优先考虑非贪婪量词或否定字符类([^>]*),后者通常更快也更不容易出错。
测试正则的正确姿势
写好正则直接上线是新人最容易犯的错误。正确的流程是这样的:
- 先在可视化测试工具里调,不要直接在代码里调。 把真实样本贴进正则测试工具,它会实时高亮所有匹配、列出捕获分组、标出非法语法,改一下模式马上能看到效果,比在代码里
console.log快得多。 - 准备正反两组测试样本。 正例要覆盖你预期的各种合法变体(比如带
+号的邮箱、带端口号的 URL);反例同样重要——邮箱少个@、日期出现2026-13-45、IP 出现300.1.1.1,这些”看起来差不多”的输入必须匹配失败。 - 注意标志位(flags)。 同一个模式加上
g(全局)、i(忽略大小写)、m(多行,让^和$匹配每行而不是整个字符串)之后行为完全不同,测试环境里的标志必须和线上代码一致。 - 警惕灾难性回溯。 嵌套量词(比如
(a+)+)遇到精心构造的输入时,匹配时间可能呈指数增长,甚至卡死服务。如果模式里有”重复套重复”的结构,务必用长的不匹配字符串测一下耗时。
记不住具体符号怎么写很正常,用的时候随手查一下正则语法速查表,比硬背高效。正则是一门”用着用着就会了”的手艺:先把这 10 个模式用熟,遇到新需求时在它们的基础上改,比从零开始啃语法书要轻松得多。