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

正则表达式实用指南:从零到一的上手攻略
浅草丶纳凉解密正则表达式:程序员的文本匹配利器
如果你和曾经的我一样,每次看到正则表达式都头皮发麻,那这篇文章就是为你准备的。
别怕,正则表达式没那么玄乎。说白了,它就是一种超强的文本“查找与替换”工具。小到检查用户输入的邮箱格式是否正确,大到从上万行日志里捞出你想要的那条信息,都离不开它。它就是程序员处理文本的瑞士军刀。
这篇指南不会讲得天花乱坠,只讲最常用、最核心的那些部分,保证你能快速上手,解决掉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 **:英文世界的百科全书,极其详尽。
去动手试试吧,这才是掌握一门技术的最好方式。