正则表达式是处理字符串的强大工具,它有自己特定的语法结构,可以用来实现字符串的检索、替换、匹配验证。对于爬虫来说,有了它,从HTML里提取想要的信息也是非常的方便。
- 优点:速度快,效率高,准确度高。
- 缺点:新手上手难度有点高
不过只要你掌握了正则编写的逻辑关系,写出一个提取页面内容的正则其实并不复杂。
1 正则的语法
使用元字符进行排列组合用来匹配字符串,在线测试正则表达式https://tool.oschina.net/regex/
2 re模块
看完了上面正则表达式语法和匹配的相关介绍,也许会很懵,不用着急。通过下面的介绍示例很快就能掌握。
在Python中需要通过正则表达式对字符串进⾏匹配的时候,可以使⽤⼀个python自带的模块,名字为re。
正则表达式的大致匹配过程是:
- 依次拿出表达式和文本中的字符比较,
- 如果每一个字符都能匹配,则匹配成功;一旦有匹配不成功的字符则匹配失败。
- 如果表达式中有量词或边界,这个过程会稍微有一些不同。
2.1 match
match只能从字符串的开头进行匹配 ,返回的是match对象,匹配不成功则返回None,拿数据需要group()方法。
re.match(pattern, string, flags=0)
第一个参数传入正则表达式,第二个参数传入要匹配的字符串
import re content='hello 123 python!' result=re.match('h',content) print(result) print(result.group()) #运行结果 <re.Match object; span=(0, 1), match='h'> h ------ content='hello 123 python!' result=re.match('123',content) print(result) #运行结果 None
2.2 search
检查字符串的任意位置,匹配到了第一个结果,就会返回这个结果,如果匹配不上search返回的则是None。
import re content='hello 123 python!' result=re.search('123',content) print(result) print(result.group()) #运行结果 <re.Match object; span=(6, 9), match='123'> 123
2.3 findall
findall查找所有,返回list。
示例:查找字符串中所有的副词
import re text = "He was carefully disguised but captured quickly by police." rule="\w+ly" # 匹配规则,\w匹配字母、数字、下划线,+与前面相连用来匹配多个字母 result=re.findall(rule, text) print(result) #运行结果 ['carefully', 'quickly']
2.4 sub
除了使用正则表达式提取信息外,有时候还可以借助它来修改文本。
sub(pattern, repl, string, count=0, flags=0)
通过使用 repl 替换在 string 最左边非重叠出现的 pattern 而获得的字符串。 如果样式没有找到,则不加改变地返回 string。
示例:删除文本中所有的数字
import re text = "24he234l234lo 65p23y23t234ho7n" result=re.sub("\d+","",text) print(result) #运行结果 hello python
2.5 compile
这个方法可以将正则字符串编译成正则表达式对象,以便在后面的匹配中复用。
prog = re.compile(pattern) result = prog.match(string) #等价于 result = re.match(pattern, string)
下面在补充一个finditer方法,返回的是迭代器 从迭代器中拿到内容需要.group()
obj = re.compile(r"\d+") #多个地方进行使用 ret= obj.finditer("我的电话是:10086,我女朋友的电话是:10010") for i in ret: print(i.group()) #运行结果 10086 10010
3 实战注意事项
3.1 贪婪与非贪婪
惰性匹配 .*? 当出现多给匹配结果时 选尽可能少的结果 让星号尽可能少的出现结果 。
贪婪匹配 .* 与惰性相反,让星号尽可能多的出现结果 。
3.2 标志修饰符
正则表达式可以包含一些可选标志修饰符,来控制匹配的模式。
import re text="""http:\\PYTHON.org very good """ result=re.match(r'^http.*?(py\w+).*?good',text) print(result) # 运行结果 None ------ # 添加修饰符 text="""http:\\PYTHON.org very good """ result=re.match(r'^http.*?(py\w+).*?good',text,re.I) print(result) # 运行结果 <re.Match object; span=(0, 26), match='http:\\PYTHON.org very good'>
3.3 原始字符串表示法
正则表达式用反斜杠字符 ('\') 表示特殊形式,或是允许在使用特殊字符时,不引发它们的特殊含义。 这与 Python 的字符串字面值中对相同字符出于相同目的的用法产生冲突;例如,要匹配一个反斜杠字面值,用户可能必须写成 '\\\\' 来作为模式字符串,因为正则表达式必须为 \\,而每个反斜杠在普通 Python 字符串字面值中又必须表示为 \\。
解决办法是对于正则表达式样式使用 Python 的原始字符串表示法;在带有 'r' 前缀的字符串字面值中,反斜杠不必做任何特殊处理。 因此 r"\n" 表示包含 '\' 和 'n' 两个字符的字符串,而 "\n" 则表示只包含一个换行符的字符串。 样式在 Python 代码中通常都使用原始字符串表示法。
import re text='http:\\python.org' result=re.search('\\\\python',text) print(result) # 运行结果 <re.Match object; span=(5, 12), match='\\python'> ------ text='http:\\python.org' result=re.search(r'\\python',text) #差异点 print(result) #运行结果 <re.Match object; span=(5, 12), match='\\python'>