写爬虫,不会正则怎么行? (2)

但是描述中还有 \d 和 \D,数字不都是 ASCII 字符吗?这是什么意思?别忘了,还有 全角和半角

s = '0123456789'    # 全角数字
re.search('\d+', s, re.U).group()

结果:

0123456789

(2)re.M
多行匹配的模式其实也不常用,很少有一行行规整的数据。

s = 'aaa\r\nbbb\r\nccc'

re.findall('^[\s\w]*?$', s)
re.findall('^[\s\w]*?$', s, re.M)

结果:

['aaa\r\nbbb\r\nccc']        # 单行模式
['aaa\r''bbb\r''ccc']    # 多行模式

(3)re.S
这个简单,直接看个例子。

s = 'aaa\r\nbbb\r\nccc'

re.findall('^.*', s)
re.findall('^.*', s, re.S)

结果:

['aaa\r']
['aaa\r\nbbb\r\nccc']

(4)re.X
用法如下:

rc = re.compile(r"""
\d+ # 匹配数字
# 和字母
[a-zA-Z]+
"""
, re.X)
rc.search('123abc').group()

结果:

123abc

注意,用了 X 修饰符后,正则中的所有空格会被忽略,包括正则里面的原本有用的空格。如果正则中有需要使用空格,只能用 \s 代替。

(5)(?aiLmsux)
修饰符不仅可以代码中指定,也可以在正则中指定。(?aiLmsux) 表示了以上所有的修饰符,具体用的时候需要哪个就在 ? 后面加上对应的字母,示例如下,(?a) 和 re.A 效果是一样的:

s = '123abc你好'
re.search('(?a)\w+', s).group()
re.search('\w+', s, re.A).group()

结果是一样的:

123abc
123abc
1.3、贪婪与懒惰

当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。

s = 'aabab'
re.search('a.*b', s).group()    # 这就是贪婪
re.search('a.*?b', s).group()   # 这就是懒惰

结果:

aabab
aab

简单来说:

所谓贪婪,就是尽可能 的匹配;

所谓懒惰,就是尽可能 的匹配。

*、+、{n,} 这些表达式属于贪婪;

*?、+?、{n,}? 这些表达式就是懒惰(在贪婪的基础上加上 ?)。

2、正则进阶 2.1、捕获分组 语法 描述
(exp)   匹配exp,并捕获文本到自动命名的组里  
(?Pexp)   匹配exp,并捕获文本到名称为 name 的组里  
(?:exp)   匹配exp,不捕获匹配的文本,也不给此分组分配组号  
(?P=name)   匹配之前由名为 name 的组匹配的文本  

注意:在其他语言或者网上的一些正则工具中,分组命名的语法是 (?<name>exp) (?'name'exp) ,但在 Python 里,这样写会报错:This named group syntax is not supported in this regex dialect。Python 中正确的写法是:(?P<name>exp)

示例一:

分组可以让我们用一条正则提取出多个信息,例如:

s = '姓名:张三;性别:男;电话:138123456789'
m = re.search('姓名[::](\w+).*?电话[::](\d{11})', s)
if m:
    name = m.group(1)
    phone = m.group(2)
    print(f'name:{name}, phone:{phone}')

结果:

name:张三, phone:13812345678

示例二:

(?P<name>exp) 有时还是会用到的, (?P=name) 则很少情况下会用到。我想了一个 (?P=name) 的使用示例,给大家看下效果:

s = '''
<name>张三</name>
<age>30</age>
<phone>138123456789</phone>
'''


pattern = r'<(?P<name>.*?)>(.*?)</(?P=name)>'
It = re.findall(pattern, s)

结果:

[('name', '张三'), ('age', '30'), ('phone', '138123456789')]
2.2、零宽断言 语法 描述
(?=exp)   匹配exp前面的位置  
(?<=exp)   匹配exp后面的位置  
(?!exp)   匹配后面跟的不是exp的位置  
(?<!exp)   匹配前面不是exp的位置  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjjyy.html