正则表达式笔记
正则表达式笔记
参考教程 https://www.runoob.com/regexp/regexp-tutorial.html
正则表达式通常用于表示满足特定规则的字符串, 因此可用于匹配文本内容, 并从中提取信息
正则表达式基本内容
普通字符
正则表达式中, 认为数字, 字母, unicode 文字以及非元字符的符号为普通字符
对于表达式中的普通字符, 表现与一般的字符串匹配相同, 仅当文本的字符以及相对位置与其相同才能通过匹配
转义字符
与一般格式化字符串相同, 正则表达式中可通过转义符 \
加内容表示特殊字符
通常可用于与元字符组合, 表示其原本代表的字符
此外还可用于表示非打印字符, 常用的有
\n
匹配换行符\t
匹配制表符\xNN
匹配 ASCII 字符, 其中XX
为字符的十六进制编码\uNNNN
匹配 Unicode 字符, 其中XXXX
为字符的十六进制编码
元字符
正则表达式中主要包含如下元字符, 这些元字符都具有特殊含义, 需要通过 \
转义才能表示原本代表的字符
虽然部分情况下直接使用元字符是合法的, 但为了避免歧义, 建议表示任意元字符时都需要转义
字符类
普通字符只能表示一个位置的一个字符, 可通过字符类表示字符, 此时该位置能够使用一类字符匹配
如果希望匹配一类特定特征的字符串, 应使用或运算
内置字符类
- 以
\<内容>
表示一类相同性质的字符, 常用的有\w
所有字母, 数字, 下划线,\W
则取反\d
表示所有数字,\D
则取反\s
表示所有空格, 换行等空白字符,\S
则取反
- 以元字符或
\<内容>
表示特殊位置, 不能被重复限定修饰$
文本内容的结尾位置, 不匹配具体字符^
文本内容的起始位置, 不匹配具体字符, 例如^...$
将使用整个文本内容进行匹配\b
表示与单词相邻的空格或边界, 例如\b\w+\b
将匹配所有单词\B
表示不与空格相邻的单词, 例如er\B
可以匹配verb
中的erb
- 元字符
.
表示除换行\n
外的所有字符
自定义字符类
- 通过
[]
包裹一系列普通字符或内置字符类, 此时该位置可以匹配其中的任意一个字符- 例如
[123]
可以匹配1, 2, 3
三个字符中任意一个
- 例如
- 当出现
^
时, 将表示取反, 即该位置可以匹配除其中出现字符外的任意字符- 例如
[^123]
可以匹配除1, 2, 3
外的任意字符
- 例如
- 对于在编号上连续的一系列 ASCII 或 unicode 字符, 可通过
-
连接首尾表示- 例如
[0-9]
匹配所有数字,[a-z]
匹配所有小写字母 - 例如
[!-/ :-@ \[-` {-~]
匹配空格与所有 ASCII 符号 (注意分了四段, 存在空格是为了方便观察, 如果仅匹配符号可删去)
- 例如
重复限定
重复限定是一种修饰, 用于修饰其左侧最邻近的包括字符类在内的任意字符
{n}
必须重复匹配n
次, 例如o{2}
与oo
匹配{n,}
至少匹配n
次, 例如o{2,}
与ooo
匹配, 但与o
不匹配{n,m}
至少匹配n
次, 但最多匹配m
次- 元字符
*
, 匹配零次或多次, 等价于{0,}
- 元字符
+
, 匹配一次或多次, 等价于{1,}
- 元字符
?
, 匹配零次或一次, 等价于{0,1}
在重复限定中, 正则表达式总是遵守让左侧的字符匹配尽可能多次的原则, 即贪婪原则
内容选择
通过 ()
包裹任意正则表达式, 可以表示
- 对被包裹正则表达式匹配内容的选择
- 表示一类满足被包裹正则表达式的子字符串
或运算
- 通过
|
连接两个正则表达式可用于表示匹配任意一个表达式, 且以左侧的表达式优先- 例如表达式
(\d+|\w+)
匹配字符串12A
时, 将分别匹配12
与A
- 例如表达式
- 或运算通常与内容选择混合使用, 以此表示部分位置的或运算
- 例如表达式
(fi|da|ba)sh
可与字符串fish
,dash
,bash
匹配
- 例如表达式
重复内容选择
内容选择也可以配合重复限定使用, 表示重复出现的一类子字符串
- 通过
(...)?
可用于表示该子字符串允许出现一次或不出现
提取选择内容
在使用正则表达式的字符串替换功能时, 还可在替换字符串中使用 $n
表示选择内容, 实现选择内容的提取
n
为提取第n
个选择内容, 从1
开始索引- 只有最外层的内容选择能被提取, 嵌套在内部的不能被提取
- 例如
((da|fi)sh)er
匹配字符串fisher
时,$1
提取到的是fish
- 例如
- 对于重复内容选择, 只会提取最右侧的选择内容, 如果内容提取则为空
- 例如
(\d+A)+
匹配字符串12A24A
时,$1
提取到的是24A
- 例如
(\d{3})?\w
匹配字符串A
时,$1
提取到的是空
- 例如
- 当使用
(?:)
表示内容选择时, 即将?:
添加在正则表达式前修饰选择, 不会提取此处选择的内容- 类似的定位断言并不用于选择, 自然也不能被提取
- 对于特定的编程语言下的实现, 提取内容可能体现为返回的匹配结果数组, 通常索引
0
为整个被匹配的字符串
引用选择内容匹配
除了提取被选择的内容, 还可以将被选择的内容用于匹配
- 使用
\n
可引用第n
个选择内容, 注意n
为数字且索引规则与提取选择内容相同 - 仅当子字符串与之前提取的选择内容完全相同才能通过匹配
- 对于重复内容选择, 同样只会使用最右侧的选择内容
- 例如
(\d+A)+ \1
匹配字符串12A24A 24A
通过, 但不匹配字符串12A24A 12A
定位断言
定位断言是一种特殊的定位方法, 不表示具体字符, 用于表示匹配内容位于特定类型的子字符串旁边
此处仅介绍其中的先行正向断言, 关于更多介绍可参考 https://www.runoob.com/w3cnote/reg-lookahead-lookbehind.html
先行正向断言 (?=...)
, 其中 ...
为断言正则表达式
- 表示满足断言正则表达式的子字符串左侧位置, 且对其右侧没有限制
- 例如
a(?=\d)
可以匹配右侧与数字相邻的 字母a
, 如a1
, 但不匹配1a
或ab
- 允许使用多个断言修饰同一个位置
- 类似的还有负向正向断言
(?!...)
, 此时子字符串不能满足给出的断言正则表达式
一般通过以下形式使用断言
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)\w{6,18}$
用于匹配任意至少包含一个大小写字母与数字的, 满足\w
要求, 且长度在6-18
的字符串- 其中各项断言如
(?=.*[a-z])
中,.*
表明限定内容位置不限,[a-z]
则表明要求出现的内容
通过(?=.*<regex>)
的方式使用断言, 可用于表示对于内容任意位置应至少出现一处符合正则表达式<regex>
的子字符串 - 去除断言剩余的
^\w{6,18}$
则表明对输入内容的基本要求 - 以上方法主要用于密码的匹配, 通过分解为
^(?=.*[a-z]).+$
与$\w{6,8}$
等可实现对密码各项要求的单独检查
- 其中各项断言如
^(?!.*\.min\.css$)(.+)\.css$
用于匹配以.css
为结尾, 但不以.min.css
为结尾文件的文件名- 其中通过断言
(?!.*\.min\.css$)
提前排除了所有满足.*\.min\.css$
的字符串
通过^(?=.*<regex>)
的方式使用断言, 可用于排除一类字符串中的特定子类 - 结尾不使用断言, 注意, 正向断言一般与
.*
等任意字符匹配配合才有意义, 否则直接匹配即可不需要断言
- 其中通过断言
([^;]+)(?=\.min\.css)
从一串以;
为间隔的文件名列表字符串中, 提取以.min.css
为后缀的文件名
修饰符
修饰符可用于指定正则表达式的匹配策略, 对于特定编程语言下的实验, 可能体现为匹配模式
- 不区分大小写
i
- 全局匹配
g
匹配时对所有输入内容进行匹配 - 多行匹配
m
元字符^, $
改为匹配内容各行的开头与结尾, 相当于对各行分别匹配 - 特殊控制
s
元字符.
将匹配所有字符 (默认.
不包含换行\n
)
在正规表示正则表达式时, 会使用 /<regex>/[modify]
的形式
<regex>
正则表达式主题[modify]
可选的修饰符
常用正则表达式
参考正则表达式例子 * https://www.runoob.com/regexp/regexp-example.html
* https://docs.python.org/zh-cn/3/library/re.html#regular-expression-examples
正则表达式测试 https://www.jyshare.com/front-end/854/
[\u4E00-\u9FA5]
表示中文字符集^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[\x20-\x7E]{8,20}$
表示必须包含字母与数字, 由 8 到 20 个可打印 ASCII 字符组成的密码