正则表达式是我们进行项目开发经常使用的一组表达式。比如如何判断用户姓名是否正确,邮箱格式是否符合规则正则表达式就是很好的处理方式。
同样的,爬虫也能够使用正则表达式。也就是说,表达式的出现就是为了能够简洁。
1、正则表达式的一行胜千言
1.1 如何胜千言
比如我们要表达以下内容:
'PY'
'PYY'
'PYYY'
'PYYYY'
'PYYYYY'
...
此时我们如何在我们的输出项表达如上的内容呢?
正则表达式表示如下:
PY+
这句话的意思在于是表达以‘PY’开头,后面表示的一个或者无穷个Y。
再看看如下举例:我们要设计一个以‘PY’开头,后续存在不多于10个字符,后续字符不能是P或者Y。
PY[^PY]{0,10}
总之,正则表达式是一种很有意思的语言,是一个通用的字符串表达框架,能够表达一种易理解,将目标字符以简洁化的工具。
1.2 具体实际
正则表达式库可以应用在很多方面。
- 表达文本类型的特征,这种实际应用可以发现病毒或者入侵文件等等
- 查找或替换一组字符串
- 匹配字符的全部或者部分内容
我们可以看到,我们使用正则表达式的框架语法在于是对目标字符的简洁化处理。
2、正则表达式语法
正则表达式是由字符和操作符组成:
操作符 | 说明 | 实例 |
---|---|---|
. | 表示任何单个字符 | |
[] | 字符集,对单个字符给出范围限定 | 如[abc]表示a、b、c,[a-z]表示从a到z |
[^ ] | 非字符集,就是对单个字符给出排除范围 | [^abc]就是非a或者非b或者非c |
* | 前一个字符0次或者无限次扩展 | abc*认为ab、abc、abcc |
+ | 前一个字符1次或者无限次扩展 | abc+认为abc、abcc |
? | 前一个字符0次或者1次扩展 | abc?认为ab、abc |
| | 左右表达式任意一个 | abc|def表示abc、def |
除此之外,我们还有以下表达的经典正则表达式:
^[A-Za-z]+$ 由26个字母组成的字符串。这里注意,此时的^应该是异或符号
^[A-Za-z0-9]+$ 由26个字母和数字组成的字符串
^-?\d+$ 这个是整数形式的字符串。注意,这里的负号是可以取的,所以后面加上?意思在于可以是负数
^[0-9]*[1-9][0-9]*$ 正整数的字符串形式
[1-9]\d{5} 中国境内邮政编码,为6位(1-9加上后面的5位数)
再进一步来,我们来用正则表达式来匹配ip地址:
首先格式如下:
\d+.\d+.\d+.\d+ 这种就是根据格式划分
\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 这是根据数值
以上都是不精确的匹配值。下面再看:
我们将0-99表示如下:[1-9]?\d
100-199表示如下:1\d{2}
200-249表示如下:2[0-4]\d
250-255表示如下:25[0-5]
四种取或并整合如下:
(([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5]).){3}([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])
3、Re库的使用
Re库主要是字符串的匹配,调用方法很简单,即import re
。
3.1 Re库的表示类型
其中首先介绍其表示类型:
re库采用的是raw String类型表示正则表达式,表示为:r’text’
比如如下:
r'[1-9]\d{5}' 表达邮政编码
原生字符串是不包括斜杠(转义符),不将其编译。因为在基本的String类型时,我们要额外添加\以转义。
3.2 Re库的功能函数
函数 | 说明 |
---|---|
re.search() | 在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象 |
re.match() | 从一个字符串的开始位置起匹配正则表达式,返回match对象 |
re.findall() | 搜索字符串,以列表类型返回全部能匹配的子串 |
re.split() | 将一个字符串按照正则表达式匹配的结果进行分割,返回列表类型 |
re.finditer() | 搜索字符串,返回一个匹配类型的迭代类型,每个迭代元素是match对象 |
re.sub() | 在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串 |
3.3 Re库主要属性
这里以re.search(pattern,string,flags=0)为例子:
这个方法中三个参数中,前两个顾翻译思意也能明白其中大致。
pattern意思是正则表达式的字符串或者原生字符串表示,
string是待匹配字符串,
我们主要讲flags,即正则表达式的使用标记。
常用标记 | 说明 |
---|---|
re.I re.IGNORECASE | 忽略正则表达式的大小写,即[A-Z]也能匹配小写的字符 |
re.M re.MULTILINE | 正则表达式中的^操作符能够将给定字符串的每行当做匹配开始 |
re.S re.DOTALL | 正则表达式中的.操作符能够匹配所有的字符串,默认匹配除了换行外的所有字符 |
3.4 Re库调用的方式
在使用Re库进行字符操作时,我们可以通过下面的函数来完成面向对象的调用。
regex = re.compile(pattern,flags=0)
此时的regex才是正则表达式的对象,我们就可以使用regex对象调用其方法。方法就是前面的函数内容。当然此时我们已经给对象赋予pattern,所以后续的函数调用只需要写入要改变的String字符即可。
4、match对象
match对象在前面的函数方法都会被返回。即很多函数的返回就是一个match对象。那么理解match对象就显得比较重要。
4.1 match对象的属性和方法
属性 | 说明 |
---|---|
.string | 待匹配的文本 |
.re | 匹配时使用的pattern对象 |
.pos | 正则表达式搜索文本的开始位置 |
.endpos | 正则表达式搜索文本的结束位置 |
就是我们通常写的实体类或者是结构体一样,我们会在这个对象中赋予上面四个内容以标记一个match对象内部的数据。
然后我们再了解该对象的方法。
方法 | 说明 |
---|---|
.group(0) | 获得匹配后的字符串 |
.start() | 匹配字符串在原始字符串的开始位置 |
.end() | 匹配字符串在原始字符串的结束位置 |
.span() | 返回(.start,.end) |
5、Re库的贪婪匹配和最小匹配
这个地方就是实际查找的字符中会遇到的问题。在一个很大的文本中我们会遇到符合正则表达式格式的字符串,那么我们要匹配哪些内容呢?
其中Re默认是采用最长的子串,就是贪婪匹配。
当然我们也会找最小的内容,那么我们可以记住下面的内容:
操作符 | 说明 |
---|---|
*? | 前一个字符0次或者无限次扩展,最小匹配 |
+? | 前一个字符1次或者无限次扩展,最小匹配 |
?? | 前一个字符0次或者1次扩展,最小匹配 |
{m,n}? | 扩展前一个字符m到n此,最小匹配 |
我们通常实现最小匹配,就在我们需要辨认的地方增添一个?即可。
总结
正则表达式是表达一组简单的字符串的一种规则,是一种简洁字符串表示的框架。
我们在使用Re中需要先使用Compile方法生成一个正则表达式对象,我们才能够使用后续的方法。
其中在正则对象使用的方法中我们要了解match对象的内容,它就是一个简单的包括属性和方法的结构体或者实体类。
并且最后在进行字符匹配能够掌握贪婪和最小匹配的方法