学习意图
正则表达式作为Python爬虫应用中基本知识,想掌握爬虫技术则需对正则表达式有系统认识及学习
步入正题
注意
此文为学习python中正则表达式,故需引入re模块,即import re
一.定义及基本术语
定义
:正则表达式是一个特殊的字符序列,一个字符串是否与我们所设定的这样的字符序列相匹配普通字符
:大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。元字符
:由于普通字符只能匹配与自身相同的字符,那么正则表达式的灵活性和强大的匹配功能就不能完全展现,于是正则表达式中规定了一系列的特殊字符,这些字符不是按照字符的直接量进行匹配的,而是具有特殊的语义,例如:? ^ $ . * + ? = ! : | \ / ( ) [ ] { }贪婪匹配
:尽可能匹配最长的字符串,且Python默认情况下是贪婪匹配模式非贪婪匹配
: 尽可能匹配最短的字符串- 注:一系列的普通字符和元字符构成了正则表达式
二.作用及简单应用场景
- 作用:快速检索文本,实现一些替换文本的操作
- 应用场景:
- 检测一串数字是否是电话号码
- 检查一个字符串是否符合email
- 把一个文本里指定的单词替换为另外一个单词
三.re模块中函数
- re.findall() 结果返回列表形式
- re.sub()替换一个字符串为另一个字符串
- re.match()
待更
- re.search()·代更·
一.单个字符为一个匹配单元
- 检查字符串中是否含有某个单词
- 只用到普通字符构成的正则表达式
import re
a = 'C|C++|Java|C#|Python|Javascript'
r = re.findall('Python',a)#普通字符组成的正则表达式
if len(r) > 0:#返回的列表中有内容
print('字符串中包含该编程语言')
print(r)
else:
print('No')
等价操作(非正则表达式)
a = 'C|C++|Java|C#|Python|Javascript'
print(a.index('Python') > -1)
print('Phthon in a')
- 抽出字符串中的数字字符
- 代表多个普通字符的一个元字符构成正则表达式
import re
a = 'C0C++1Java2C#3Python4Javascript'
r = re.findall('\d',a)#元字符组成的正则表达式
if len(r) > 0:#返回的列表中有内容
print('字符串中包含数字字符')
print(r)
else:
print('字符串中不含数字字符')
- 匹配多个符合条件单词
- 元字符表达区间
import re
a = 'abc, acc, adc, aec, afc, ahc'
r = re.findall('a[^c-f]c',a)#像a和c一样的普通字符一般是用来定界的
if len(r) > 0:#返回的列表中有内容
print('字符串中符合条件单词:',end = '')
print(r)
else:
print('字符串中无符合条件单词')
- 匹配出整个单词,而非单个字母
- 限定正则表达式匹配次数的数量词
>>> import re
>>> a = 'python j1ava 1php'
>>> r = re.findall('[a-z]{3,6}',a)#数量词表示区间用','而非'-'
>>> print(r)
['python', 'ava', 'php']
>>> import re
>>> a = 'pytho0python1pythonn2'
>>> r = re.findall('python*',a)
>>> print(r)
['pytho', 'python', 'pythonn']
数量词还有'?'和'+'等,与此示例类似,故不再赘述
- 此运行结果证明,数量词限定的是数量是从第一个匹配到的字符算起,如果之后每个字符都符合且匹配数量符合了数量词限定则视为匹配成功,否则不视为匹配成功或匹配出的长度等于数量词。
- 一般情况下,当数量词有区间时,正则表达式尽可能匹配多的字符,这是因为常规下默认贪婪匹配模式。后面示例给出非贪婪匹配模式。
- 同一表达式匹配不同结果
- 贪婪与非贪婪算法
>>> import re
>>> a = 'python j1ava 1php'
>>> r = re.findall('[a-z]{3,6}?',a)#数量词后加'?'表示非贪婪匹配模式
>>> print(r)
['pyt','hon','ava', 'php']
>>>import re
>>>a = 'pytho0python1pythonn2'
>>>r = re.findall('python?',a)
>>>print(r) #很容易错认为['pytho','python']
['pytho', 'python', 'python']
- 为匹配设定边界
- 使用’^‘表示从字符串开始数的位数,’$'表示从字符串结尾数的位数
>>>import re
>>>qq = '123456789'
>>>r = re.findall('^\d{4,8}&',qq) #假设qq为4-8位长
>>>print(r)
[]
- 将某一字符串替换为另一个字符串
>>>import re
>>>language = 'PythonjavaPHPC#'
>>>r = re.findall('C#','GO',language)
>>>print(r)
['PythonjavaPHPGO']
>>>import re
>>>s = 'ABC3721D86'
>>>def convert(value):
>>> matched = value.group()
>>> if int(matched) >= 6:
>>> return '9'
>>> else:
>>> return '0'
>>>r = re.sub('\d',convert,s)
>>>print(r)
ABC0900D99
二.多个字符为一个匹配单元(组)
10. 多个字符构成一组进行匹配
>>>import re
>>>a = 'PythonPythonPythonPython'
>>>r = re.findall('(Python){2}',a);
>>>print(r)#共匹配出两组
['Python', 'Python']
三.匹配模式参数
11. 匹配时不区分大小写
12. [x] 使用参数’re.I’
>>>import re
>>>language = 'PythonjavaPHPC#'
>>>r = re.findall('c#',language,re.I)
>>>print(r)
['C#']
- ‘.’元字符匹配空白字符
>>>import re
>>>language = 'PythonjavaPHPC#\n'
>>>r = re.findall('c#',language,re.S|re.I)
>>>print(r)
['C#\n']
- 多个参数同时出现用’|'间隔
附表
来自:百度百科,链接:正则表达式
元字符 | 描述 |
---|---|
^ | 匹配输入字行首 |
$ | 匹配输入行尾 |
* | 匹配前面的子表达式任意次,*等价于{0,} |
+ | 匹配前面的子表达式一次或多次(大于等于1次),+等价于{1,}。 |
? | 匹配前面的子表达式零次或一次,?等价于{0,1}。 |
? | 当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪.默认是贪婪的 |
. | 匹配除“\n”和"\r"之外的任何单个字符。 |
\d | 匹配一个数字字符。等价于[0-9]。 |
\D | 匹配一个非数字字符。等价于[^0-9]。 |
\s | 匹配任何不可见字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。 |
\S | 匹配任何可见字符。等价于[^ \f\n\r\t\v]。 |
\w | 匹配包括下划线的任何单词字符。类似但不等价于“[A-Za-z0-9_]” |
\W | 匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。 |
[xyz] | 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。 |
[^xyz] | 负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“plin”任一字符。 |
[a-z] | 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。 |
[^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。 |
- 注意
- 一般概括字符集(\w,\s,\d等)大写和小写表示相反的匹配结果。例:
\d
匹配数字字符,但\D
匹配非数字字符