正则表达式笔记
正则表达式笔记
参考教程 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 字符组成的密码