1. 首页
  2. Blog
  3. 令爷原创

正则表达式入门教程

5分钟搞懂 —— 正则表达式 (by 令爷)

引言

正则表达式是一种强大的文本匹配和处理工具。它就像是一个神奇的模式识别系统,能帮助我们在文本中查找、匹配和替换特定的字符串。无论是验证用户输入、处理文本文件,还是进行数据分析,正则表达式都能大显身手。

让我们通过一个简单的例子开始。假设你需要在一篇文章中找出所有的电话号码,你会怎么做?如果手动查找,这将是一项耗时的工作。但使用正则表达式,我们可以用一行代码就能完成这个任务。

1. 基础匹配

在深入学习正则表达式之前,我们先从最简单的开始 - 普通字符的匹配。

当我们在文本中查找一个确切的词时,可以直接使用这个词作为正则表达式。比如:

  • 要查找文本中的"hello",直接使用正则表达式 hello
  • 要查找"2024",直接使用 2024

这就是最基本的正则表达式。它会精确匹配你指定的字符。

2. 元字符

元字符是正则表达式的基本构建块,用于定义匹配模式。以下是几个常用的元字符及其功能:

元字符 说明 记忆提示
. 匹配除换行符以外的任意字符 小圆点,代表多种字符,但不包括换行符
\w 匹配字母、数字、下划线或汉字 “word”的缩写,代表“单词字符”
\s 匹配任意的空白符 “space”的缩写,匹配空白字符
\b 匹配单词边界 “bound”的缩写,表示单词的边界
\d 匹配数字 “digit”的缩写,仅匹配数字
^ 匹配字符串的开始 表示字符串的起始位置
$ 匹配字符串的结束 表示字符串的结束位置

有了元字符之后,我们就可以利用这些元字符来写一些简单的正则表达式了:

  1. 匹配有 abc 开头的字符串:\babc 或者 ^abc
  2. 匹配 8 位数字的 QQ 号码:^\d\d\d\d\d\d\d\d$
  3. 匹配 1 开头 11 位数字的手机号码:^1\d\d\d\d\d\d\d\d\d\d$

上述正则表达式^1\d\d\d\d\d\d\d\d\d\d$ 虽然功能明确,但在可读性和简洁性方面存在不足。为了提升表达式的简洁性和可维护性,可以通过量词进行简化。例如,可以使用 重复限定符 {n} 语法来指定重复次数,从而将表达式简化为 ^1\d{10}$。这种写法不仅更加简洁,而且更易于理解和维护。

3. 重复限定符

下面我们来看一些限定符,拓展部分增加了示例说明和使用场景:

语法 说明 拓展
* 重复零次或更多次 示例:a* 匹配字符串中出现零次或多次的字符 a,如匹配空字符串、aaaaaa 等。常用于匹配可选的字符或字符序列。例如,在正则表达式中用于匹配文件名中的可选扩展名,如 file.* 可匹配 file.txtfile.jpg 等。
+ 重复一次或更多次 示例:a+ 匹配字符串中至少出现一次的字符 a,如匹配 aaaaaa 等,但不匹配空字符串。常用于匹配必须存在的字符或字符序列。例如,在匹配电话号码时,[0-9]+ 可以匹配任意长度的数字序列。
? 重复零次或一次 示例:a? 匹配字符串中出现零次或一次的字符 a,如匹配空字符串或 a。常用于匹配可选的字符。例如,在匹配日期格式时,(\d{1,2})-(\d{1,2})-(\d{2,4})? 可以匹配 01-0101-01-2024
{n} 重复 n 次 示例:a{3} 匹配字符串中恰好出现 3 次的字符 a,如匹配 aaa。常用于精确匹配固定数量的字符。例如,在匹配固定长度的验证码时,[0-9]{6} 可以匹配 6 位数字验证码。
{n,} 重复 n 次或更多次 示例:a{3,} 匹配字符串中至少出现 3 次的字符 a,如匹配 aaaaaaa 等。常用于匹配至少出现 n 次的字符序列。例如,在匹配连续的空格时,\s{2,} 可以匹配至少两个连续的空格。
{n,m} 重复 n 到 m 次 示例:a{2,4} 匹配字符串中出现 2 到 4 次的字符 a,如匹配 aaaaaaaaa。常用于匹配字符出现次数在一定范围内的场景。例如,在匹配密码时,[a-zA-Z0-9]{6,12} 可以匹配长度为 6 到 12 位的密码。

这些语法在正则表达式中非常常用,通过合理使用它们,可以实现灵活的字符串匹配和提取功能。

有了这些限定符之后,我们就可以对之前的正则表达式进行改造了,比如:

  1. 匹配 8 位数字的 QQ 号码:^\d{8}$
  2. 匹配 1 开头 11 位数字的手机号码:^1\d{10}$
  3. 匹配银行卡号是 14~18 位的数字:^\d{14,18}$
  4. 匹配以 a 开头的,0 个或多个 b 结尾的字符串:^ab*$

看上去更简洁了!

4. 分组

从上面的例子(4)中看到,* 限定符是作用在与他左边最近的一个字符。

如果我想要 ab 同时被 * 限定那怎么办呢?

正则表达式中用小括号 () 来做分组,也就是括号中的内容作为一个整体。因此当我们要匹配多个 ab 时,我们可以这样:如匹配字符串中包含 0 到多个 ab 开头:^(ab)*

5. 转义

我们看到正则表达式用小括号来做分组。

如果要匹配的字符串中本身就包含小括号,那是不是冲突?应该怎么办?

针对这种情况,正则提供了转义的方式,也就是要把这些元字符、限定符或者关键字转义成普通的字符,做法很简单,就是在要转义的字符前面加个斜杠,也就是 \ 即可。如:要匹配以 (ab) 开头:^\((ab)\)*

6. 条件或

回到我们刚才的手机号匹配,我们都知道:国内号码都来自三大网,它们都有属于自己的号段,比如联通有 130/131/132/155/156/185/186/145/176 等号段。
假如让我们匹配一个联通的号码,那按照我们目前所学到的正则,应该无从下手的,因为这里包含了一些并列的条件,也就是“或”,那么在正则中是如何表示“或”的呢?

正则用符号 | 来表示或,也叫做分支条件,当满足正则里的分支条件的任何一种条件时,都会当成是匹配成功。那么我们就可以用“或”条件来处理这个问题:^(130|131|132|155|156|185|186|145|176)\d{8}$

7. 区间

正则提供一个元字符中括号 [] 来表示区间条件。限定 0 到 9 可以写成 [0-9],限定 A-Z 写成 [A-Z],限定某些数字 [165]

那上面的正则我们还改成这样:^((13[0-2])|(15[56])|(18[5-6])|145|176)\d{8}$

8. 反义

我们会有有一些不是数组,不是字符的需求,所以就有了反义词。

代码/语法 说明
\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了 x 以外的任意字符

9. 常用表达式

9.1 数字表达式

  • 数字:^[0-9]*$
  • n 位的数字:^\d{n}$
  • 至少 n 位的数字:^\d{n,}$
  • m-n 位的数字:^\d{m,n}$
  • 零和非零开头的数字:^(0|[1-9][0-9]*)$
  • 非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(\.[0-9]{1,2})?$
  • 带 1-2 位小数的正数或负数:^(\-)?\d+(\.\d{1,2})$
  • 正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
  • 有两位小数的正实数:^[0-9]+(\.[0-9]{2})?$
  • 有 1~3 位小数的正实数:^[0-9]+(\.[0-9]{1,3})?$
  • 非零的正整数:^[1-9]\d*$^([1-9][0-9]*){1,3}$^\+?[1-9][0-9]*$
  • 非零的负整数:^\-[1-9][0-9]*$^-[1-9]\d*$
  • 非负整数:^\d+$^[1-9]\d*|0$
  • 非正整数:^-[1-9]\d*|0$^((-\d+)|(0+))$
  • 非负浮点数:^\d+(\.\d+)?$^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
  • 非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$^(([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
  • 正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$^(([09]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[09]+)|([0-9]*[1-9][0-9]*))$
  • 负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$((([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
  • 浮点数:^(-?\d+)(\.\d+)?$^-?([19]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$

9.2 字符表达式

  • 汉字:^[一-龥]{0,}$
  • 英文和数字:^[A-Za-z0-9]+$^[A-Za-z0-9]{4,40}$
  • 长度为 3-20 的所有字符:^.{3,20}$
  • 由 26 个英文字母组成的字符串:^[A-Za-z]+$
  • 由 26 个大写英文字母组成的字符串:^[A-Z]+$
  • 由 26 个小写英文字母组成的字符串:^[a-z]+$
  • 由数字和 26 个英文字母组成的字符串:^[A-Za-z09]+$
  • 由数字、26 个英文字母或者下划线组成的字符串:^\w+$^\w{3,20}$
  • 中文、英文、数字包括下划线:^[一龥A-Za-z0-9_]+$
  • 中文、英文、数字但不包括下划线等符号:^[一-龥A-Za-z0-9]+$^[一龥A-Za-z0-9]{2,20}$
  • 可以输入含有 ^%&',;=?$" 等字符:[^%&',;=? $\x22]+
  • 禁止输入含有 ~ 的字符:[^~\x22]+

9.3 常用表达式

  • Email 地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+ ([-.]\w+)*$
  • 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zAZ0-9][-a-zA-Z0-9]{0,62})+\.?
  • Internet URL:[a-zA-z]+://[^\s]*^[http://([\w]+\.)+[\w-]+(/[\w-./?%&=]*)?$](http://([\w]+\.)+[\w-]+(/[\w-./?%&=]*)?$`)
  • 手机号码:^(13[09]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7| 8|9])\d{8}$
  • 电话号码("XXX-XXXXXXX"、"XXXXXXXXXXXX"、"XXX-XXXXXXX"、"XXXXXXXXXXX"、"XXXXXXX" 和 "XXXXXXXX"):^(\ (\d{3,4}-)|\d{3.4}-)?\d{7,8}$
  • 国内电话号码(0511-4405222、02187888822):\d{3}-\d{8}|\d{4}-\d{7}
  • 电话号码正则表达式(支持手机号码,3-4 位区号,7-8 位直播号码,1-4 位分机号):((\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})| (\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})| (\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)
  • 身份证号(15 位、18 位数字),最后一位是校验位,可能为数字或字符 X:(^\d{15}$)|(^\d{18}$)|(^\d{17} (\d|X|x)$)
  • 帐号是否合法(字母开头,允许 5-16 字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
  • 密码(以字母开头,长度在 6~18 之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$
  • 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在 8-10 之间):^(?=.*\d)(?=.*[az])(?=.*[A-Z])[a-zA-Z0-9]{8,10}$
  • 强密码(必须包含大小写字母和数字的组合,可以使用特殊字符,长度在 8-10 之间):^(?=.*\d)(?=.*[az])(?=.*[A-Z]).{8,10}$
  • 日期格式:^\d{4}-\d{1,2}-\d{1,2}
  • 一年的 12 个月(01~09 和 1~12):^(0?[1-9]|1[0-2])$
  • 一个月的 31 天(01~09 和 1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$

原创文章,作者:曾确令,如若转载,请注明出处:https://www.zengqueling.com/zzbdsrmjc/

联系我们

15602395067

在线咨询:点击这里给我发消息

邮件:eden7@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code