Skip to content
On this page

regex

🕒 Published at:

测试正则表达式是否匹配:regex101.com

正则表达式的概念

正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。 举例:

  • \d可以匹配一个数字
  • \w可以匹配一个字母或数字
  • .可以匹配任意字符
  • \s可以匹配一个空格(也包括Tab等空白符)
    所以,\d\s\w.可以匹配'1 2a.'

常用的正则表达式

  • \d可以匹配一个数字
  • \w可以匹配一个字母或数字
  • .可以匹配任意字符
  • \s可以匹配一个空格(也包括Tab等空白符)
  • *表示任意个字符(包括0个)
  • +表示至少一个字符
  • ?表示0个或1个字符
  • {n}表示n个字符
  • {n,m}表示n-m个字符
  • \s可以匹配一个空格(也包括Tab等空白符)
  • ^表示行的开头
  • $表示行的结束

正则表达式要注意win和linux的换行符的不同

  • win的换行符是\r\n
  • linux的换行符是\n
js
// 用于匹配win的换行符
const reg = /\r\n/g
// 用于匹配linux的换行符
const reg = /\n/g
//实例
// 匹配包含在 --- --- 之间的内容 linux下的
const frontMatterRegex = /---\n([\s\S]*?)\n---/m; 
//win下的
const frontMatterRegex = /---\r\n([\s\S]*?)\r\n---/m;

/---\n([\s\S]*?)\n---/m

  • ---\n 匹配 ---\n
  • ([\s\S]*?) 匹配任意字符
  • \n 匹配 \n
  • --- 匹配 ---
  • /m 表示多行匹配

- ([\s\S]*?)

  • () 表示分组
  • [\s\S] 表示任意字符
  • *? 表示非贪婪匹配

正则表达式的分组

  • () 表示分组
  • [] 表示范围

正则表达式的非贪婪匹配

  • *? 表示非贪婪匹配

正则表达式的多行匹配

  • /m 表示多行匹配

/^date:\s*(.*)/m

  • ^ 表示行的开头
  • date: 表示date:
  • \s* 表示任意个空格
  • (.*) 表示任意字符
  • /m 表示多行匹配

正则表达式修饰符

  • i 修饰符用于执行对大小写不敏感的匹配。
  • g 修饰符用于执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
  • m 修饰符用于执行多行匹配。

正则表达式的元字符

  • \d 任意数字
  • \D 任意非数字
  • \w 任意字母数字下划线
  • \W 任意非字母数字下划线
  • \s 任意空白符
  • \S 任意非空白符
  • \b 匹配单词边界
  • \B 匹配非单词边界
  • \n 匹配换行符
  • \r 匹配回车符
  • \t 匹配制表符
  • \v 匹配垂直制表符
  • \f 匹配换页符
  • \0 匹配空字符
  • \xhh 匹配十六进制数
  • \uhhhh 匹配 Unicode 字符

正则表达式的量词

    • 重复零次或更多次
    • 重复一次或更多次
  • ? 重复零次或一次
  • {n} 重复n次
  • {n,} 重复n次或更多次
  • {n,m} 重复n到m次

正则表达式的贪婪模式和非贪婪模式

  • 贪婪模式:正则表达式默认是贪婪模式,即匹配尽可能多的字符
  • 非贪婪模式:正则表达式默认是贪婪模式,即匹配尽可能多的字符

正则表达式的分组

  • () 表示分组
  • [] 表示范围

正则表达式的分支条件

  • | 表示分支条件

正则表达式的反义

  • \W 匹配任意非字母数字下划线
  • \S 匹配任意非空白符
  • \D 匹配任意非数字
  • \B 匹配非单词边界
  • [^x] 匹配除了x以外的任意字符

正则表达式的零宽断言

  • (?=exp) 匹配exp前面的位置
  • (?<=exp) 匹配exp后面的位置
  • (?!exp) 匹配后面跟的不是exp的位置
  • (?<!exp) 匹配前面不是exp的位置
  • (?#comment) 注释,忽略括号内的内容

正则表达式的负向零宽断言

  • (?<!exp) 匹配前面不是exp的位置
  • (?!exp) 匹配后面跟的不是exp的位置

正则表达式的注释

  • (?#comment) 注释,忽略括号内的内容

正则表达式的运算符优先级

  • \ 转义符
  • (), ( ?: ), (?=), [] 圆括号和方括号
  • *, +, ?, {n}, {n,}, {n,m} 限定符
  • ^, $, \任何元字符、任何字符 定位点和序列(即:位置和顺序)
  • | 替换,"或"操作

正则表达式的模式修正符

  • i 修饰符用于执行对大小写不敏感的匹配。
  • g 修饰符用于执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
  • m 修饰符用于执行多行匹配。

re模块

Python提供re模块,包含所有正则表达式的功能。由于Python的字符串本身也用\转义,所以要特别注意:

python
s = 'ABC\\-001' # Python的字符串
# 对应的正则表达式字符串变成:
# 'ABC\-001'

因此我们强烈建议使用Python的r前缀,就不用考虑转义的问题了:

python
s = r'ABC\-001' # Python的字符串
# 对应的正则表达式字符串不变:
# 'ABC\-001'

先看看如何判断正则表达式是否匹配:

python
import re
re.match(r'^\d{3}\-\d{3,8}$', '010-12345')

上面的代码表示:

  • 创建一个正则表达式对象
  • 用该正则表达式去匹配字符串
  • 如果匹配成功,返回一个Match对象,否则返回None。 所以我们用变量m来保存匹配的结果:
python
>>> import re
>>> m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
>>> m
<_sre.SRE_Match object; span=(0, 9), match='010-12345'>
>>> m.group(0)
'010-12345'
>>> m.group(1)
'010'
>>> m.group(2)
'12345'

如果正则表达式中定义了组,就可以在Match对象上用group()方法提取出子串来。 注意到group(0)永远是原始字符串,group(1)、group(2)……表示第1、2、……个子串。 提取子串非常有用。来看一个更凶残的例子:

python
>>> t = '19:05:30'
>>> m = re.match(r'^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:([0-5][0-9])\:([0-5][0-9])$', t)
>>> m.groups()
('19', '05', '30')