51dev.com IT技术开发者社区

51dev.com 技术开发者社区

爬虫入门【4】正则表达式用法简介

ymnets阅读(346)2020-03-25 收藏0次评论

特殊字符的含义

首先推荐使用r'string'来定义字符,免去转义字符的影响。
python">#'.',点号,在默认模式中,匹配任何一个字符,除了新的行newline。如果DOTALL标记指定了,那么还可以匹配newline。
# '^',匹配字符串的开始
# '$',匹配字符串的结束。比如foo匹配foo或者foobar,但是foo$只能匹配到foo。
# '*',匹配0个或者多个字符,比如ab*,可以匹配a,ab,abbbb等
# '+',匹配1个或者多个字符,比如ab+,可以匹配ab,或者abbbb
# '?',匹配0或者1个字符,比如ab?只能匹配a或者ab。
#贪婪模式,*?+,都是贪婪模式的,会尽可能多的匹配字符,在后面加上一个?则会变为非贪婪模式,尽可能匹配少的字符。
#我们一般用非贪婪模式。

# {m},指定匹配的数量,比如a{6}表示将匹配6个a字符,而不是5个,准确匹配。
# {m,n},匹配在m~n个字符之间,包含m和n,比如a{3,5}将匹配3-5个a字符,一般会取上限来匹配。
# 如果不指定m或者n,则表示没有上限,下限不能低于0个
# {m,n}?,非贪婪模式的匹配,尽可能匹配少,取下限m来匹配。

# [],用于创造一个字符的集合,字符可以单独出现或者使用0-9,a-z这种格式。
# 比如:[amk]会匹配a,m或者k字符。[a-z]将会匹配a-z之间的任何一个字符。[0-5][0-9]匹配从00-59的所有字符。
# 如果在[]中包含一个特殊字符的集合,比如[(+*)],这些特殊字符将会失去其特殊含义,只匹配字面意义,'('')''+''*'。
# 如果在[]的开始有一个'^',比如[^5],将会匹配任何一个不是5的字符。

# '|',A|B,AB是任意的RE表达式,可以匹配A或者B
# (...),括号内的表达式将作为分组,从表达式左边开始每遇到一个分组的左括号,编号+1。分组表达式作为一个整体,可以后接数量词。
# 比如,(abc){2}匹配abcabc,a(123|456)c匹配a456c或者a123c。
# (?P<name>...),分组,除了原有的编号外,指定一个额外的别名,比如:(?P<id>abc){2},可以匹配abcabc,通过.'id'来访问。
# <number>,引用编号为<number>的分组匹配到的字符串。比如(d)abc1,可以匹配1abc1,或者5abc5
# (?P=name),引用别名为<name>的分组匹配到的字符串,比如(?P<id>d)abc(?P=id),可以匹配1abc1,5abc5等。

# d,表示数字,0-9之间的一个,比如adc,可以匹配a1c;
# D,表示非数字,也可以用[^d]来代替,
# s,表示空白字符
# S,表示非空白字符
# w,表示单词字符,[A-Za-z0-9_]
# W,表示非单词字符。
# A,仅匹配字符串的开头,Aabc可以匹配abc。
# ,仅匹配字符串结尾,abc,匹配abc

Re模块

介绍常用的几个方法

#首先要导入re模块
import re

re.compile(pattern,flags=0)

#将原生字符串对象传到compile方法中,可以获得一个pattern匹配模式
pattern=re.compile(r'hello')
#这个pattern可以用于进一步的匹配
#flag参数,指匹配模式,可以选则
re.I#忽略大小写
re.M#多行模式
re.S#点任意匹配,
re.L#
re.U
re.X#详细模式,这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。

re.match(pattern, string, flags=0)

match方法会从要匹配的string的开头开始,尝试匹配pattern,一直向后,如果遇到无法匹配的字符,就返回None,如果匹配未结束已经到达string的末尾也会返回None,表示匹配失败。匹配成功会返回True,以及匹配到的内容的group。
举个例子:(来自http://cuiqingcai.com/977.html)

pattern=re.compile(r'hello')
result1=re.match(pattern,'hello')
result2=re.match(pattern,'helloo world')
result3=re.match(pattern,'helo world')
result4=re.match(pattern,'hello world')

if result1:
    print(result1.group())
else:
    print('1匹配失败!')
if result2:
    print(result2.group())
else:
    print('2匹配失败!')
if result3:
    print(result3.group())
else:
    print('3匹配失败!')
if result4:
    print(result4.group())
else:
    print('4匹配失败!')

hello
hello
3匹配失败!
hello
#对于返回的这个结果,我们再通过一个例子来了解一下:
import re
m=re.match(r'(w+) (w+)(?P<sign>.*)','hello world!')#单词+空格+单词+任意字符

print(m.string)#获取匹配时使用的文本
print(m.re)#获取匹配时使用的pattern对象
print(m.pos)#文本中开始搜索的位置
print(m.endpos)#返回结束搜索的位置
print(m.lastindex)#最后一个被捕获的分组在文本中的索引
print(m.lastgroup)#最后一个最捕获的分组的别名
print(m.group())#获得一个或多个分组截获的字符串,如果指定多个参数,将会以元祖形式返回
print(m.group(1,2))#指定多个参数
print(m.groups())#以元组形式返回所有分组截获的字符串
print(m.groupdict())#返回具有别名的组的别名为Key,字符串为value的字典,不包含别名的组不统计
print(m.start(2))#返回指定的组截获的子串在string中的起始索引
print(m.end(2))#返回指定的组在string中的结束索引
print(m.span(2))#返回(start(group),end(group))
hello world!
re.compile('(\w+) (\w+)(?P<sign>.*)')
0
12
3
sign
hello world!
('hello', 'world')
('hello', 'world', '!')
{'sign': '!'}
6
11
(6, 11)

re.search(pattern, string, flags=0)

类似与match方法,但是match会检测re是不是在string的开始位置就能够匹配到,而search会扫描整个string来匹配。match方法只有在0位置匹配成功的话才会返回,如果不是开始i位置,即使后面由匹配,也会返回None。

import re
pattern=re.compile(r'world')
match=re.search(pattern,'hello world!')
if match:
    print(match.group())
world

re.fullmatch(pattern, string, flags=0)

re.split(pattern, string, maxsplit=0, flags=0)

将string按照匹配的子串分割后返回列表,maxsplit参数指定最大分割次数,不指定的话会全部分割。

import re
pattern=re.compile(r'd+')
split=re.split(pattern,'one1two2three3four4')
print(split)
['one', 'two', 'three', 'four', '']

re.findall(pattern, string, flags=0)

搜索string,以列表的形式返回全部能匹配的子串。

import re
pattern = re.compile(r'd+')
print(re.findall(pattern,'one1two23three3four4'))
['1', '23', '3', '4']

re.finditer(pattern, string, flags=0)

搜索string,返回一个顺序访问每一个匹配结果的迭代器

import re
pattern=re.compile(r'd+')
for m in re.finditer(pattern,'one1two23three3four4'):
    print(m.group())
1
23
3
4

re.sub(pattern, repl, string, count=0, flags=0)

使用repl替换string中的每一个匹配的子串后返回替换的字符串。
repl可以是一个方法,这个方法应该只接受一个match对象作为参数,并且返回一个字符串用于替换。
count可以指定最多替换次数,不指定的话就全部替换。

import re
pattern=re.compile(r'(w+) (w+)')
string='i say, hello world!'
print(re.sub(pattern,r'2 1',string))

def func(m):
    return m.group(1).title()+' '+m.group(2).title()
print(re.sub(pattern,func,string))
say i, world hello!
I Say, Hello World!

Pattern,正则表达式对象

上面介绍的所有方法都适用于pattern。

如果您觉得感兴趣的话,可以添加我的微信公众号:一步一步学Python

以上就是爬虫入门【4】正则表达式用法简介的全部内容。