python爬取准备二 正则表达式

re模块

re 模块使 Python 语言拥有全部的正则表达式功能。
compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。

转义符

正则表达式中用“\”表示转义,而python中也用“\”表示转义,当遇到特殊字符需要转义时,你要花费心思到底需要几个“\”。所以为了避免这个情况,推荐使用原生字符串类型(raw string)来书写正则表达式。

方法很简单,只需要在表达式前面加个“r”即可,如下:

r'\d{2}-\d{8}'
r'\bt\w*\b'

常用函数

python爬取准备二 正则表达式

re.match()

从字符串的起始位置匹配,匹配成功,返回一个匹配的对象,否则返回None

语法:re.match(pattern, string, flags=0)
pattern:匹配的正则表达式
string:要匹配的字符串
flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等;flags=0表示不进行特殊指定

可选标志如下:

修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志

python爬取准备二 正则表达式

re.search()

扫描整个字符串并返回第一个成功的匹配对象,否则返回None

语法:re.search(pattern, string, flags=0)

re.match与re.search的区别

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配(注意:仅仅是第一个)

re.findall()

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表

注意: match 和 search 是匹配一次,而findall 匹配所有

re.split()

根据正则表达式中的分隔符把字符分割为一个列表并返回成功匹配的列表.

re.sub()

用于替换字符串中的匹配项

语法: re.sub(pattern, repl, string, count=0)

pattern : 正则中的模式字符串。
repl : 替换的字符串,也可为一个函数。
string : 要被查找替换的原始字符串。
count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。

re.compile()

compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,然后就可以用编译后的正则表达式去匹配字符串

pattern : 一个字符串形式的正则表达式 
flags :可选,表示匹配模式,比如忽略大小写,多行模式等

贪婪匹配和非贪婪匹配

贪婪匹配:匹配尽可能多的字符; 非贪婪匹配:匹配尽可能少的字符

python的正则匹配默认是贪婪匹配

>>> re.match(r'^(\w+)(\d*)$','abc123').groups()
('abc123', '')
>>> re.match(r'^(\w+?)(\d*)$','abc123').groups()
('abc', '123')

表达式1:
\w+表示匹配字母或数字或下划线或汉字并重复1次或更多次;\d*表示匹配数字并重复0次或更多次。
 分组1中(\w)是贪婪匹配,它会在满足分组2(\d*)的情况下匹配尽可能多的字符,
因为分组2(\d*)匹配0个数字也满足,所以分组1就把所有字符全部匹配掉了,分组2只能匹配空了。

表达式2:在表达式后加个?即可进行非贪婪匹配,如上面的(\w+?),
因为分组1进行非贪婪匹配,也就是满足分组2匹配的情况下,分组1尽可能少的匹配,
这样的话,上面分组2(\d*)会把所有数字(123)都匹配,所以分组1匹配到(abc)

常见匹配模式

\w  匹配字母数字及下划线
\W  匹配非字母数字下划线
\s  匹配任意空白字符,等价于 [\t\n\r\f].
\S  匹配任意非空字符
\d  匹配任意数字,等价于 [0-9]
\D  匹配任意非数字
\A  匹配字符串开始
\Z  匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串
\z  匹配字符串结束
\G  匹配最后匹配完成的位置
\n  匹配一个换行符
\t  匹配一个制表符
^   匹配字符串的开头
$   匹配字符串的末尾。
.   匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[…] 用来表示一组字符,单独列出:[amk] 匹配 ‘a’,‘m’或’k’
[^…]    不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
*   匹配0个或多个的表达式。
+   匹配1个或多个的表达式。
?   匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
{n} 精确匹配n个前面表达式。
{n, m}  匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
a|b 匹配a或b
( ) 匹配括号内的表达式,也表示一个组

    正则式需要匹配不定长的字符串,那就一定需要表示重复的指示符。Python的正则式表示重复的功能很丰富灵活。重复规则的一般的形式是在一条字符规则后面紧跟一个表示重复次数的规则,已表明需要重复前面的规则一定的次数。

匹配规则举例

*’   0或多次匹配**

表示匹配前面的规则0次或多次。

‘+’   1次或多次匹配

表示匹配前面的规则至少1次,可以多次匹配

例:匹配以下字符串中的前一部分是字母,后一部分是数字或没有的变量名字

s = ‘ aaa bbb111 cc22cc 33dd ‘

re.findall( r’\b[a-z]+\d*\b’ , s )             #必须至少1个字母开头,以连续数字结尾或没有数字

['aaa', 'bbb111']

注意上例中规则前后加了表示单词边界的’\b’指示符,如果不加的话结果就会变成:

re.findall( r’[a-z]+\d*’ , s )

['aaa', 'bbb111', 'cc22', 'cc', 'dd']    #把单词给拆开了

大多数情况下这不是我们期望的结果。 

‘?’   0或1次匹配

只匹配前面的规则0次或1次。

例,匹配一个数字,这个数字可以是一个整数,也可以是一个科学计数法记录的数字,比如123和10e3都是正确的数字。

s = ‘ 123 10e3 20e4e4 30ee5 ‘

re.findall( r’ \b\d+[eE]?\d*\b’ , s )

['123', '10e3']

它正确匹配了123和10e3,正是我们期望的。注意前后的’\b’的使用,否则将得到不期望的结果。

精确匹配和最小匹配

Python正则式还可以精确指定匹配的次数。指定的方式是

‘{m}’      精确匹配m次

‘{m,n}’   匹配最少m次,最多n次。(n>m)

如果你只想指定一个最少次数或只指定一个最多次数,你可以把另外一个参数空起来。比如你想指定最少3次,可以写成 {3,} (注意那个逗号),同样如果只想指定最大为5次,可以写成{,5},也可以写成{0,5}。

例 寻找下面字符串中

a:3位数

b: 2位数到4位数

c: 5位数以上的数

d: 4位数以下的数

s= ‘ 1 22 333 4444 55555 666666 ‘

re.findall( r’\b\d{3}\b’ , s )            # a:3位数

['333']

re.findall( r’\b\d{2,4}\b’ , s )         # b: 2位数到4位数

['22', '333', '4444']

re.findall( r’\b\d{5,}\b’, s )           # c: 5位数以上的数

['55555', '666666']

re.findall( r’\b\d{1,4}\b’ , s )         # 4位数以下的数

['1', '22', '333', '4444']

*?’ ‘+?’ ‘??’ 最小匹配**

’ ‘+’ ‘?’通常都是尽可能多的匹配字符。有时候我们希望它尽可能少的匹配。比如一个c语言的注释 ‘/ part 1 / / part 2 */’,如果使用最大规则:

s =r ‘/ part 1 / code / part 2 /’

re.findall( r’/*.\/’ , s )

[‘/ part 1 / code / part 2 /’]

结果把整个字符串都包括进去了。如果把规则改写成

re.findall( r’/*.?*/’ , s )                    #在后面加上?,表示尽可能少的匹配

['/ part 1 /', '/ part 2 /']

猜你喜欢

转载自blog.51cto.com/13689359/2457647
今日推荐