正则表达式
正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为”元字符”)组成的文字模式
普通字符
[ABC] : 匹配 […] 内的所有字符
[^ABC] : 匹配除了 […]中字符的所有字符
[A-Z] : 表示一个区间,匹配 A - Z 范围里的字符
. : 匹配除换行符 \n \r 之外的任何单个字符,相当于[^\r\n]
\s:匹配所有空白字符
\S:匹配所有非空白字符
\w:匹配 字母、数字、下划线等价于[A-Za-z0-9_]
\d: 匹配任意一个阿拉伯数字 等价于[0-9]
非打印字符
字符 | 描述 |
---|---|
\cx | 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。 |
\f | 匹配一个换页符。等价于 \x0c 和 \cL。 |
\n | 匹配一个换行符。等价于 \x0a 和 \cJ。 |
\r | 匹配一个回车符。等价于 \x0d 和 \cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。 |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 |
\t | 匹配一个制表符。等价于 \x09 和 \cI。 |
\v | 匹配一个垂直制表符。等价于 \x0b 和 \cK。 |
特殊字符
特别字符 | 描述 |
---|---|
$ | 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n’ 或 ‘\r’。要匹配 $ 字符本身,请使用 $。 |
( ) | 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 ( 和 )。 |
* | 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *。 |
+ | 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。 |
. | 匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 . 。 |
[ | 标记一个中括号表达式的开始。要匹配 [,请使用 [。 |
? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 ?。 |
\ | 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, ‘n’ 匹配字符 ‘n’。’\n’ 匹配换行符。序列 ‘\‘ 匹配 “",而 ‘(‘ 则匹配 “(“。 |
^ | 匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 ^。 |
{ | 标记限定符表达式的开始。要匹配 {,请使用 {。 |
| | 指明两项之间的一个选择。要匹配 |,请使用 |。 |
限定符
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于 **{0,}**。 |
---|---|
+ | 匹配前面的子表达式一次或多次。例如,zo+ 能匹配 “zo” 以及 “**zoo”**,但不能匹配 “z”。+ 等价于 **{1,}**。 |
? | 匹配前面的子表达式零次或一次。例如,do(es)? 可以匹配 “do” 、 **”does”**、 “doxy” 中的 “do” 和 “does”。? 等价于 **{0,1}**。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,o{2} 不能匹配 “Bob” 中的 o,但是能匹配 “food” 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。例如,o{2,} 不能匹配 “Bob” 中的 o,但能匹配 “foooood” 中的所有 o。o{1,} 等价于 o+。o{0,} 则等价于 **o***。 |
{n,m} | m 和 n 均为非负整数,其中 n <= m。最少匹配 n 次且最多匹配 m 次。例如,o{1,3} 将匹配 “fooooood” 中的前三个 o。o{0,1} 等价于 **o?**。请注意在逗号和两个数之间不能有空格。 |
定位符
定位符用来描述字符串或单词的边界,^ 和 $ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。
字符 | 描述 |
---|---|
^ | 匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与 \n 或 \r 之后的位置匹配。 |
$ | 匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与 \n 或 \r 之前的位置匹配。 |
\b | 匹配一个单词边界,即字与空格间的位置。 |
\B | 非单词边界匹配。 |
学习计划
- 了解基本的正则表达式的语法
- 熟悉常见的正则表达式
- 使用正则表达式提取网页html完成一个爬虫项目
基本概念
正则表达式(Regular Expression)缩写为 Regex 或 Regexp,是在正则表达式语法框架内创建的字符串。
可以使用正则表达式来管理数据、执行查找、匹配或编辑等命令。
匹配
查找文件列表中,扩展名是pdf的文件
^\w+\.pdf$ |
基本匹配:查找出文本中的curious
curious |
点 . 可以匹配任何字符、包括了特殊字符和空格
字符集 [abc] ,如果一个词中的字符可以是各种字符,我们就将所有的可选字符写进括号[]中
bar ber bir bor bur |
否定字符集[^abc]
为了查找下方文本的所有单词(ber 和 bor 除外) |
字母范围 [a-z] 为了查找指定范围的字母,我们需要将起始字母和结束字母写进 [] 中,中间用连字符 - 分隔。它区分大小写
abcdefghijklmnopqrstuvwxyz |
数字范围 [0-9] 为了查找指定范围的数字,我们需要在 [] 中输入起始和结束数字,中间用连字符 - 分隔
0123456789 |
重复
重复(repetitions) 一些特殊字符用来指定一个字符在文本中重复的次数。它们分别是加号 +、星号 * 和问号 ?
星号 *(Asterisk)在字符后面加上 *,表示一个字符完全不匹配或可以匹配多次
br ber beer |
加号 + (the plus) 表示一个字符可以出现一次或多次,我们将 + 放在它后面
br ber beer |
问号 ? (the question mark) 为了表示一个字符是可选的,我们在它后面加一个 ?
color, colour |
大括号 {} 为了表示一个字符出现的确切次数,我们在该字符的末尾,将它出现的次数写进大括号 {} 中
ber beer beeer beeeer |
表示一个字符至少出现多少次,我们在该字符的末尾,将它至少应出现的次数写进大括号 {} 中,并在数字后面加上逗号 ,
ber beer beeer beeeer |
表示一些字符出现的次数在某个数字范围内,我们在该字符的末尾,将它至少和至多出现的次数写进大括号 {} 中,中间用逗号 , 分隔
ber beer beeer beeeer |
分组
括号() 对一个表达式进行分组,并用这些分组来引用或执行一些规则 为了给表达式分组,我们需要将文本包裹在 () 中
ha-ha,haa-haa |
引用组
单词 ha 和 haa 分组如下。第一组用 \1 来避免重复书写。这里的 1 表示分组的顺序。请在表达式的末尾键入 \2 以引用第二组。 |
(?:) 非捕获分组 可以对表达式进行分组,并确保它不被引用捕获
例如,下面有两个分组,但我们用 \1 引用的第一个组实际上是指向第二个组,因为第一个是未被捕获的分组 |
| 竖线 竖线允许一个表达式包含多个不同的分支。所有分支用 | 分隔。和在字符层面上运作的字符集 [abc] 不同,分支在表达式层面上运作
下面的表达式同时匹配 cat 和 rat。请在末尾添加另一个 |,并输入 dog 以匹配所有单词。 |
转义字符 \ 在书写正则表达式时,我们会用到 { } [ ] / \ + * . $^ | ? 这些特殊字符 。为了匹配这些特殊字符本身,我们需要通过 \ 将它们转义
要匹配文本中的 . 和 *,我们需要在它们前面添加一个 \ |
插入符 ^ 匹配字符串的开始
Basic Omellette Recipe |
美元符号 $ 匹配字符串的结束
让我们在 html 的后面添加 $,来查找仅在行末出现的 html |
单词字符 \w : 字母、数字、下划线
用表达式 \w 来查找文本中的单词字符。 |
非单词字符\W : 匹配除了字符、数字、下划线之外的字符
匹配除字母、数字和下划线之外的字符 |
数字字符 \d : 仅仅用来匹配数字
abcABC123 .:!? |
非数字字符 \D :用来匹配非数字字符
abcABC123 .:!? |
空白符 \s : 仅匹配空白字符
abcABC123 .:!? |
非空白符 \S:仅匹配非空白字符
abcABC123 .:!? |
零宽断言
如果我们希望正在写的词语出现在另一个词语之前或之后,我们需要使用「零宽断言」
正向先行断言 (?=)
要匹配文本中的小时值。为了只匹配后面有 PM 的数值,我们需要在表达式后面使用正向先行断言 (?=),并在括号内的 = 后面添加 PM |
负向先行断言 (?!)
要在文本中匹配除小时值以外的数字。我们需要在表达式后面使用负向先行断言 (?!),并在括号内的 ! 后面添加 PM,从而只匹配没有 PM 的数值 |
正向后行断言(?<=)
要匹配文本中的金额数。为了只匹配前面带有 $ 的数字。我们要在表达式前面使用正向后行断言 (?<=),并在括号内的 = 后面添加 \$ |
负向后行断言 (!<=)
要在文本中匹配除价格外的数字。为了只匹配前面没有 $ 的数字,我们要在表达式前用负向后行断言 (?<!),并在括号内的 ! 后面添加 \$ |
标志
标志改变表达式的输出。这就是标志也称为 修饰符 的原因。标志决定表达式是否将文本视作单独的行处理,是否区分大小写,或者是否查找所有匹配项
全局标志 /g 全局标志使表达式选中所有匹配项,如果不启用全局标志,那么表达式只会匹配第一个匹配项
domain.com, test.com, site.com |
多行标志 /m 正则表达式将所有文本视作一行。但如果我们使用了多行标志,它就会单独处理每一行。
domain.com |
忽略大小写标志 /i 使我们编写的表达式不再大小写敏感
DOMAIN.COM |
匹配规则
贪婪匹配 :正则表达式默认执行贪婪匹配。这意味着匹配内容会尽可能长
下面的示例,它匹配任何以 r 结尾的字符串,以及前面带有该字符串的文本,但它不会在第一个 r 处停止匹配 |
懒惰匹配: 与贪婪匹配不同,懒惰匹配在第一次匹配时停止
下面的例子中,在 * 之后添加 ?,将查找以 r 结尾且前面带有任意字符的第一个匹配项。这意味着本次匹配将会在第一个字母 r 处停止。 |
实际使用
匹配html文件中所有<img> 标签中的src属性
(?<=img.*src=")[\w:/\.?=\\:;&]+(?=") |