爬虫-提取信息-正则表达式

match():
从字符串起始位置匹配正则表达式

import re

content = 'Hello 123 4567 World_This is a Regex Demo'
print(len(content))
result = re.match('^Hello\s\d\d\d\s\d{4}\s\w{10}', content)
print(result)
print(result.group())
print(result.span())

re.match的参数:
^: 匹配开头
\s: 匹配空白字符
\d: 表示匹配数组(后面加{4}表示匹配四个数字)
\w: 匹配字母数字和下划线

result 代表的是整体 .group()表示的是匹配的返回结果 .span()表示匹配的是范围

匹配目标:

import re

content = 'Hello 1234567 World_This is a Regex Demo'
result = re.match('^Hello\s(\d+)\sWorld', content)
print(result)
print(result.group())
print(result.group(1))
print(result.span())

()括号将字符串括起来 group()方法传入分组的索引提取结果
.group: 匹配所有的符合的字符串
.group(1): 匹配目标
.span(): 匹配范围

通用匹配:
.*(万能匹配)

import re

content = 'Hello 1234567 World_This is a Regex Demo'
result = re.match('^Hello.*Demo$', content)
print(result)
print(result.group())
print(result.span())

从上述正则表达式中可以看到.*简化表达式的书写

贪婪和非贪婪:
有的时候.*并不能匹配到想要的结果

import re

content = 'Hello 1234567 World_This is a Regex Demo'
result = re.match('^He.*(\d+).*Demo$', content)
print(result)
print(result.group(1))
print(result.span())

.*: 会尽可能的匹配更多的字符 由于(\d+)并没有指定多少字符,所以
会尽可能的匹配,只给(\d+)留一个数字7
优化(非贪婪匹配):

import re

content = 'Hello 1234567 World_This is a Regex Demo'
result = re.match('^He.*?(\d+).*Demo$', content)
print(result)
print(result.group(1))

非贪婪匹配匹配尽可能少的字符,匹配到(\d+)他就不匹配啦,就让(\d+)去匹配啦
结论: 在匹配的时候尽可能的使用非贪婪匹配,以免造成匹配结果缺失的情况

非贪婪匹配的注意事项:

import re

content = 'http://weibo.com/comment/kEraCN'
result1 = re.match('http.*?comment/(.*?)', content)
result2 = re.match('http.*?comment/(.*)', content)
print('result1', result1.group(1))
print('result2', result2.group(1))

.*? 会尽可能少的匹配,因为后面没有什么东西可以匹配的,所以他还想匹配,但是匹配不到内容

修饰符:
修饰符来控制匹配模式

import re

content = '''Hello 1234567 World_This
is a Regex Demo
'''
result = re.match('^He.*?(\d+).*?Demo$', content)
print(result.group(1))

报错信息: 正则表达式没有匹配到这个字符串
加一个换行符(可以使.匹配到\n),在网页匹配中经常遇到

转义匹配:

import re

content = '(百度)www.baidu.com'
result = re.match('\(百度\)www\.baidu\.com', content)
print(result)

加上\可以进行转移,从而避开正则表达式的匹配规则

search():
match(方法匹配是从字符串开头匹配的,如果不是开头则会匹配失败的)

import re

content = 'Extra stings Hello 1234567 World This is a Regex Demo Extra stings'
result = re.search('Hello.*?(\d+).*?Demo', content)
print(result.group(1))

用match方法则不行,match只能匹配开头的
demo

import re

html = '''<div id="songs-list">
    <h2 class="title">经典老歌</h2>
    <p class="introduction">
        经典老歌列表
    </p>
    <ul id="list" class="list-group">
        <li data-view="2">一路上有你</li>
        <li data-view="7">
            <a href="/2.mp3" singer="任贤齐">沧海一声笑</a>
        </li>
        <li data-view="4" class="active">
            <a href="/3.mp3" singer="齐秦">往事随风</a>
        </li>
        <li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
        <li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
        <li data-view="5">
            <a href="/6.mp3" singer="邓丽君"><i class="fa fa-user"></i>但愿人长久</a>
        </li>
    </ul>
</div>'''

result = re.search('li.*?active.*?singer="(.*?)">(.*?)</a>', html, re.S)
print(result.group(1), result.group(2))
print(result.group(0))

findall():

import re

html = '''<div id="songs-list">
    <h2 class="title">经典老歌</h2>
    <p class="introduction">
        经典老歌列表
    </p>
    <ul id="list" class="list-group">
        <li data-view="2">一路上有你</li>
        <li data-view="7">
            <a href="/2.mp3" singer="任贤齐">沧海一声笑</a>
        </li>
        <li data-view="4" class="active">
            <a href="/3.mp3" singer="齐秦">往事随风</a>
        </li>
        <li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
        <li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
        <li data-view="5">
            <a href="/6.mp3" singer="邓丽君"><i class="fa fa-user"></i>但愿人长久</a>
        </li>
    </ul>
</div>'''

results = re.sub('<a.*?>|</a>', '', html)
print(results)
results = re.findall('<li.*?>(.*?)</li>', results, re.S)
for result in results:
    print(result.strip())

a节点通过sub()方法处理,最后通过findall()方法提取,达到事半功倍的效果

compile():
将正则表达式字符串编译成正则表达式对象,以后方便重复使用

import re

content1 = '2016-12-15 12:00'
content2 = '2016-12-17 12:55'
content3 = '2016-12-22 13:21'
pattern = re.compile('\d{2}:\d{2}')
result1 = re.sub(pattern, '', content1)
result2 = re.sub(pattern, '', content2)
result3 = re.sub(pattern, '', content3)

print(result1, result2, result3)

compile方法将正则表达式对象封装,以便复用(re.S等参数可以传入,以后不用重复传入了)

猜你喜欢

转载自blog.csdn.net/qq_40258748/article/details/89491416