正则常见示例

匹配数字

数字的匹配比较简单,通过我们学习的字符组,量词等就可以轻松解决。

  • 数字在正则中可以使用 \d 或 [0-9] 来表示。
  • 如果是连续的多个数字,可以使用 \d+ 或 [0-9]+。
  • 如果 n 位数据,可以使用 \d{n}。
  • 如果是至少 n 位数据,可以使用 \d{n,}。
  • 如果是 m-n 位数字,可以使用 \d{m,n}。

匹配十六进制

十六进制的数字除了有 0-9 之外,还会有 a-f(或 A-F) 代表 10 到 15 这 6 个数字,所以正则可以写成 [0-9A-Fa-f]+。

匹配手机号码

手机号应该是比较常见的,手机号段比较复杂,如果要兼容所有的号段并不容易。目前来看,前四位是有一些限制,甚至 1740 和 1741 限制了前 5 位号段。

我们可以简单地使用字符组和多选分支,来准确地匹配手机号段。如果只限制前 2 位,可以表示成 1[3-9]\d{9},如果想再精确些,限制到前三位,比如使用

1
1(?:3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[1389])\d{8}

如果想精确到 4 位,甚至 5 位,可以根据公开的号段信息自己来写一下,但要注意的是,越是精确,只要有新的号段,就得改这个正则,维护起来会比较麻烦。另外,在实际运用的时候,可能还要考虑一下有一些号码了 +86 或 0086 之类的前缀的情况。

手机号段的正则写起来其实写起来并不难,但麻烦的是后期的维护成本比较高,我之前就遇到过这种情况,买了一个 188 的移动号码,有不少系统在这个号段开放了挺长时间之后,还认为这个号段不合法。

目前公开的手机号段:

身份证

我国的身份证号码是分两代的,第一代是 15 位,第二代是 18 位。如果是 18 位,最后一位可以是 X(或 x),两代开头都不能是 0,根据规则,你应该能很容易写出相应的正则,第一代可以用 [1-9]\d{14} 来表示,第二代比第一代多 3 位数据,可以使用量词 0 到 1 次,即写成

1
[1-9]\d{14}(\d\d[0-9Xx])?

邮政编码

邮编一般为 6 位数字,比较简单,可以写成

1
\d{6}

6 位数字在其它情况下出现可能性也非常大,比如手机号的一部分,身份证号的一部分,所以如果是数据提取,一般需要添加断言,即写成 :

1
(?<!\d)\d{6}(?!\d)

日期时间

假设日期格式是 yyyy-mm-dd,如果不那么严格,我们可以直接使用

1
\d{4}-\d{2}-\d{2}

如果再精确一些,比如月份是 1-12,当为一位的时候,前面可能不带 0,可以写成 01 或 1,月份使用正则,可以表示成:

1
1[0-2]|0?[1-9]

日可能是 1-31,可以表示成:

1
[12]\d|3[01]|0?[1-9]

这里需要注意的是 0?[1-9] 应该放在多选分支的最后面,因为放最前面,匹配上一位数字的时候就停止了,正确的正则应该是:

1
\d{4}-(?:1[0-2]|0?[1-9])-(?:[12]\d|3[01]|0?[1-9])

时间格式比如是 23:34,如果是 24 小时制,小时是 0-23,分钟是 0-59,所以可以写成:

1
(?:2[0-3]|1\d|0?\d):(?:[1-5]\d|0?\d)

另外,日期中月份还有大小月的问题,比如 2 月闰年可以是 29 日,使用正则没法验证日期是不是正确的。我们也不应该使用正则来完成所有事情,而是只使用正则来限制具体的格式,比如四位数字,两位数字之类的,提取到之后,使用日期时间相关的函数进行转换,如果失败就证明不是合法的日期时间。

邮箱

1
[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+

网页标签

配对出现的标签,比如 title,一般网页标签不区分大小写,我们可以使用 (?i) 来进行匹配。在提取引号里面的内容时,可以使用 [^"]+,方括号里面的内容时,可以使用 [^>]+ 等方式。


正则常见示例
https://sunshinechen.cn/2022/12/19/正则常见示例/
作者
sunshine
发布于
2022年12月19日
许可协议