正则表达式实用指南:从零到一的上手攻略

正则表达式实用指南:从零到一的上手攻略
浅草丶纳凉解密正则表达式:程序员的文本匹配利器
如果你和曾经的我一样,每次看到正则表达式都头皮发麻,那这篇文章就是为你准备的。
别怕,正则表达式没那么玄乎。说白了,它就是一种超强的文本“查找与替换”工具。小到检查用户输入的邮箱格式是否正确,大到从上万行日志里捞出你想要的那条信息,都离不开它。它就是程序员处理文本的瑞士军刀。
这篇指南不会讲得天花乱坠,只讲最常用、最核心的那些部分,保证你能快速上手,解决掉 80%的日常问题。
热身运动:找个好用的“游乐场”
在正式开干前,你需要一个能随时测试你想法的地方。别总是在 IDE 或代码里print调试,效率太低。
强烈推荐 **regex101.com**。
这网站好在哪?它不光能告诉你匹配对了没,还会在右边把你的表达式拆开来,告诉你每一步都是什么意思。对于新手来说,这简直是神仙功能。后面我们的所有例子,你都可以直接复制进去自己试试看。
核心招式:基础语法
掌握下面这几招,你就已经入门了。
1. 限定符:控制出现的次数
这是正则表达式最基本的功能。
?问号:代表“可有可无”,也就是出现 0 次或 1 次。比如colors?可以同时匹配color和colors。*星号:代表“随便来”,出现 0 次、1 次或很多次都行。比如ab*c可以匹配ac、abc、abbbbc。+加号:和星号很像,但代表“至少要有一个”,也就是出现 1 次或很多次。ab+c就没法匹配ac了。{}花括号:让你精确控制次数。a{3}:不多不少,必须是 3 个 a。a{2,5}:最少 2 个,最多 5 个 a。a{2,}:最少 2 个,上不封顶。
2. 分组与分支:处理组合与多选
()括号:把一堆东西包起来,当成一个整体。比如你想匹配好几个连续的ab,就要用(ab)+,这样+才会作用于整个ab。|竖线:代表“或者”。I love (cats|dogs)就能匹配I love cats和I love dogs。注意括号是必须的,不然就变成I love cats或者dogs了,意思全变了。
3. 字符类:指定一个范围
[]方括号允许你自定义一个“字符集合”,只要字符属于这个集合,就能匹配。
[abc]:匹配 a、b、c 中的任意一个。[a-z]:匹配所有小写字母。[a-zA-Z0-9]:匹配所有字母和数字。[^0-9]:开头的^表示“取反”,所以这个是匹配所有非数字的字符。
4. 元字符:常用的“简写”
正则表达式的设计者早就为我们准备好了一些常用的字符类简写,省得我们每次都写方括号。
\d:任意数字,相当于[0-9]。\w:任意“单词”字符,包括字母、数字和下划线,相当于[a-zA-Z0-9_]。\s:任意空白,包括空格、Tab、换行符。.(英文句点):这是个大杀器,能匹配除了换行符之外的任何单个字符。\D,\W,\S:用大写字母表示对应小写版本的“取反”。比如\D就是匹配任意非数字字符。
5. 定位符:锚定位置
这些符号不匹配任何字符,而是匹配一个“位置”。
^:锚定一行的开始。^Hello只会匹配以 Hello 开头的行。$:锚定一行的结束。world$只会匹配以 world 结尾的行。\b:锚定一个单词的边界。用\bcat\b就能只匹配单词cat,而不会匹配到concatenate里面的 cat。
进阶心法:贪婪与懒惰
这是很多人刚开始会踩的坑。默认情况下,正则表达式是“贪婪”的。
什么意思?比如你有这么一段文本:
1 | <span><a>link</a></span> |
你想用<.+>来匹配 HTML 标签。你以为它会匹配出<span>和<a>和</a>和</span>。但结果是,它会从第一个<一直匹配到最后一个>,把整个字符串全给你。
这就是“贪婪”,+和*会尽可能多地吞掉字符。
解决方法很简单:在+或*后面加个?,让它变得“懒惰”。
用<.+?>,正则表达式就会在找到第一个匹配的>时立刻停下来。这在处理 HTML、XML 这类成对标签的文本时,几乎是必备技巧。
实战演练
理论讲完了,来点实际的。
场景一:提取十六进制颜色值
比如,从一堆 CSS 代码里找出所有像#ff6600这样的颜色值。
- 颜色以
#开头。 - 后面跟着 6 个十六进制字符,也就是
0-9或a-f(大小写不限)。 - 我们希望它是个独立的单位,不希望匹配到
#ff66000里面去。
组合起来就是:#([0-9a-fA-F]{6})\b
#匹配井号。[0-9a-fA-F]定义了十六进制字符集。{6}表示要 6 个。\b定义了单词边界。
场景二:校验 IP 地址
这个需求很常见,但也更复杂。一个简单的\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}能匹配上格式,但它也会让999.999.999.999这样的鬼东西通过,因为 IP 地址每一段的范围是 0-255。
要精确匹配,表达式会变得有点吓人。别怕,我们拆开看。
1 | \b((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\b |
这个表达式的核心就是用|把 0-255 分成了几个区间来匹配:
25[0-5]:匹配 250-2552[0-4]\d:匹配 200-2491\d{2}:匹配 100-199[1-9]?\d:匹配 0-99
然后用分组和{3}把它重复三次,再跟上最后一段。这个例子有点劝退,看不懂没关系,先理解思路,需要用的时候再回来查就行。
总结与展望
到这里,你已经掌握了正则表达式的绝大部分精华。下面这张表可以当做你的备忘录。
| 类型 | 语法 | 描述 |
|---|---|---|
| 限定符 | *, +, ?, {} | 控制数量 |
| 分支 | (a|b) | A 或 B |
| 字符类 | [...], [^...] | 集合与排除 |
| 元字符 | \d, \w, \s, . | 常用简写 |
| 定位符 | ^, $, \b | 匹配位置 |
| 模式 | +, * (贪婪) vs +?, *? (懒惰) | 匹配策略 |
正则表达式能做的远不止这些,还有捕获组、反向引用、零宽断言等更高级的玩法,那些可以让你写出更精妙、更高效的表达式。不过饭要一口一口吃,先把今天学的这些在实际项目中用起来,你会发现处理字符串的效率大大提升。如果感兴趣的话后续可能会在出几篇相关的博客。
如果你想继续深入,下面这几个资源质量非常高:
- **正则表达式 30 分钟入门教程**:中文启蒙经典,作者 deerchao。
- **Regular Expressions Tutorial **:英文世界的百科全书,极其详尽。
去动手试试吧,这才是掌握一门技术的最好方式。












