python爬虫 Day 7

赤发鬼
• 阅读 754

正则表达式下

位置匹配和非贪婪匹配

位置匹配

有时候需要对出现的位置有要求,比如开头、结尾、单词等

表达式匹配
^在字符串开始的地方匹配,符号本身不匹配任何字符
$在字符串结束的地方匹配,符号本身不匹配任何字符
\b匹配一个单词边界,也就是单词和空格之间的位置,符号本身不匹配任何字符
\B匹配非单词边界,即左右两边都是\w范围或者左右两边都不是\w范围时的字符缝隙

非贪婪匹配

1.贪婪匹配--定义
在重复匹配时,正则表达式默认总是尽可能多的匹配,这被称为贪婪匹配
2.非贪婪匹配--定义
匹配尽可能少的字符 (使用?)

re模块常用方法

方法描述返回值
compile根据包含正则表达式的字符串创建模式对象re对象
search在字符串中查找第一个匹配的对象或者None
match在字符串的开始处匹配模式在字符串开头匹配到的对此昂或者None
split根据模式的匹配项来分割字符串分割后的字符串列表
findall列出字符串中模式的所有匹配项所有匹配到的字符串列表
sub将字符串所有的pat匹配项用repl替换完成替换后的新字符串

flag匹配模式

默认情况下 flags=0

匹配模式描述
re.AASCII字符模式
re.I使匹配对大小写不敏感,也就是不区分大小写的模式
re.L做本地化识别(locale-aware)匹配
re.M多行匹配,影响^和$
re.S使.这个通配符能够匹配包括换行在内的所有字符,针对多行匹配
re.U根据Unicode字符集解析字符。这个标志影响\w,\W,\b,\B
re.X该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解

分组功能

1.定义
是指去已经匹配到的内容再筛选出需要的内容,相当于二次过滤
2.过程
(1)实现分组靠圆括号()
(2)获取分组的内容靠的是group()、groups()
3.注意
re模块里的几个重要方法在分组上,有不同的表现形式,需要区别对待

代码

(1)代码greedy

import re

# s 表示待匹配的数据
s = '<div>abc</div><div>def</div>'
# 需求:<div>abc</div>

# .用来匹配任意不换行的一个字符 * 匹配0到任意次
ptn1 = r'<div>.*</div>'
result1 = re.match(ptn1, s)
print(result1.group())
# 贪婪匹配 一直匹配 返回最长的匹配结果

# 非贪婪匹配 匹配尽可能少的字符 那么如何得到非贪婪匹配呢
# ? .*? .+? {m,n}?
ptn2 = r'<div>.*?</div>'
result2 = re.match(ptn2, s)
print(result2.group())

(2)代码re_examples_1

import re

# 位置匹配
# result1 = re.match(r'\d{11}', '12345678910')
# print(result1.group())
# result2 = re.match(r'1[2-9]\d{9}', '12345678910')
# print(result2.group())
# result3 = re.match(r'1[2-9]\d{9}', '11345678910')
# print(result3.group())   # 报错

# result4 = re.match(r'^1[2-9]\d{9}$', '12345678910')
# print(result4.group())
# result5 = re.match(r'^1[2-9]\d{9}', '123456789101')
# print(result5.group())
# result6 = re.match(r'^1[2-9]\d{9}$', '123456789101')
# print(result6.group())   # 报错 $ 表示只能有那么多位数字

(3)代码re_examples_2

import re

def fn(ptn, lst):
    for i in lst:
        result = re.match(ptn, i)
        if result:
            print('匹配成功!匹配结果为:', result.group())
        else:
            print('匹配失败!')

# . 用来匹配除了换行符以外的任意字符
# lst =['abc', 'abbb', 'other', 'add',  'aba']
# ptn = r'ab.'
# fn(ptn, lst)

# [] 用来匹配[]列举的字符
# lst = ['man', 'mbn', 'mdn', 'mun', 'nba']
# ptn = r'm[abcf]n'
# fn(ptn, lst)

# ^ 取反
# lst = ['man', 'mbn', 'mdn', 'mun', 'nba']
# ptn = r'm[^abcf]n'
# fn(ptn, lst)

# \d  用来匹配一个数字[0-9]
# lst = ['py5', 'py24', 'pyxxx', 'other']
# ptn = r'py\d'
# fn(ptn, lst)

# lst = ['7.1', '569', '4.51', '555']
# ptn = r'\d\.\d'
# fn(ptn, lst)

# \D 匹配非数字 \d的补集
# lst = ['py.5', 'py2', 'pyxxx', 'other']
# ptn = r'py\D'
# fn(ptn, lst)

# \s 匹配空白等
# lst = ['hello world', 'helloxxxx', 'hello,world', 'hello\fworld', 'hello\tworld', 'hello\nworld']
# ptn = r'hello\sworld'
# fn(ptn, lst)

# \S
# lst = ['hello world', 'helloxxxx', 'hello,world', 'helloxworld']
# ptn = r'hello\Sworld'
# fn(ptn, lst)

# \w 匹配字母数字下划线
# lst = ['1-age', 'a-age', '&-age', '_-age',' -age']
# ptn = r'\w-age'
# fn(ptn, lst)

# \W
# lst = ['1-age', 'a-age', '&-age', '_-age',' -age']
# ptn = r'\W-age'
# fn(ptn, lst)

# * 出现0到任意次
# lst = ['hello', 'java', 'python', 'h', 'xxx']
# ptn = r'[hp][a-z]*'
# fn(ptn, lst)

# + 至少出现一次
# lst = ['hello', 'java', 'python', 'h', 'xxx']
# ptn = r'[hp][a-z]+'
# fn(ptn, lst)

# {n} 重复匹配n次
# lst = ['hello', 'java', 'python', 'h', 'xxxxxxxx']
# ptn = r'\w{6}'
# fn(ptn, lst)

# {m,n} 大于等于m次 小于等于n次  但其实如果是在基本符号后面的话 只要前面符合表达式 后面有多少位都可以
# 在python中 默认是贪婪的
# lst = ['hello', 'jav', 'python', 'h', 'xxxxxxxx']
# ptn = r'\w{3,4}'
# fn(ptn, lst)

# 位置匹配
# lst = ['123@qq.com', 'abc@yy.com', 'xxx@qq.com.cn']
# ptn = r'\w+@qq.com'
# fn(ptn, lst)

lst = ['123@qq.com', 'abc@yy.com', 'xxx@qq.com.cn']
ptn = r'\w+@qq.com$'  #  非贪婪
fn(ptn, lst)

(4)代码re_examples_3

import re

# compile(pattern, flags=0)
# pat = re.compile(r'abc')   # 正则表达式
# print(pat)   # re.compile('abc')
# x1 = pat.match('abc123')
# print(x1)   # <re.Match object; span=(0, 3), match='abc'>
# x2 = pat.match('abc123').group()  # 待匹配表达式
# print(x2)   # abc
# x3 = pat.match('ABC123').group()
# print(x3)   # 报错 大小写区分 该如何解决呢?--不区分大小写 re.I
# pat2 = re.compile(r'abc', re.I)
# x4 = pat2.match('ABC123').group()
# print(x4)    # ABC


# match(pattern, string, flags=0)
# match会从头就开始匹配 返回第一个成功匹配的结果 否则就返回None
# y1 = re.match(r'abc', '123abc456abc789').group()
# print(y1)  # 报错
# y2 = re.match(r'abc', 'abc456abc789').group()
# print(y2)  # abc
# y3 = re.match(r'abc', 'abcabcabc789').group()
# print(y3)  # abc  为什么不会贪婪匹配呢? \d 只是用来匹配单个字符


# search(pattern, string, flags=0)
# 只要待匹配的数据里面有正则表达式 就可以匹配成功 且只会打印第一次匹配成功的数据
# z1 = re.search(r'abc', '123abc456abc789').group()
# print(z1)
# ^ 表示开头 即开头必须是abc
# z2 = re.search(r'^abc', '123abc456abc789').group()
# print(z2)   # 报错
# z3 = re.search(r'^abc', 'abc456abc789').group()
# print(z3)


# findall(pattern, string, flags=0)
# 寻找待匹配表达式中符合正则表达式的所有内容 同时以列表的形式打印出来
# r1 = re.findall(r'abc', '123abc456abc789').group()
# print(r1)   # 报错 因为list不可以使用group方法
# r2 = re.findall(r'abc', '123abc456abc789')
# print(r2)  # ['abc', 'abc'] 可以选择遍历或者索引
# r3 = re.findall(r'abcd', '123abc456abc789')
# print(r3)  # 匹配失败就返回空列表


# split(pattern, string, maxsplit=0, flags=0)
# s = '1*2-3+4/5'   # 需求:将数字单独拿出来 多种方式

# findall
# e1 = re.findall(r'\d{1,}', s)
# print(e1)
# e2 = re.findall(r'\d+', s)
# print(e2)
# e3 = re.findall(r'\d', s)
# print(e3)
# e4 = re.findall(r'\d*', s)
# print(e4)  # 打印结果有问题 含有0(无)

# split
# s1 = re.split(r'[\+\-\*\/]', s)  # 注意要转义
# print(s1)

# maxsplit 最大分割
# u1 = re.split(r'[\+\-\*\/]', s, maxsplit=2)
# print(u1)  # ['1', '2', '3+4/5'] 切两刀
# u2 = re.split(r'[\+\-\*\/]', s, maxsplit=0)
# print(u2)  # 不变
# u3 = re.split(r'[\+\-\*\/]', s, maxsplit=3)
# print(u3)  # >=4 都一样 不变


# sub(pat, repl, string, count=0, flags=0)
s = "i can't stand my poor python, i like python"
l1 = re.sub(r'i', 'I', s)
print(l1)   # 代替 i代替I

(5)代码re_group

import re

# s是待匹配的数据
s = 'apple price is $22, banana price is $33'
# 需求: 获取$22 $33
# 分组就是去匹配到的数据里面再次进行筛选 相当于二次过滤
result1 = re.search(r'.*\$\d+.*\$\d+', s)
print(result1)  # <re.Match object; span=(0, 39), match='apple price is $22, banana price is $33'>
result2 = re.search(r'.*(\$\d+).*(\$\d+)', s)  # 进行分组()
print(result2.group())
print(result2.group(0))
print(result2.group(1))
print(result2.group(2))
print(result2.groups())
print(result2.groups(0))
print(result2.group()[0])  # 是指索引为0的字符 和上述不一样


"""
result.group()/result.group(0) 匹配整个分组
result.group(1) $22 匹配第一个分组
result.group(2) $33 匹配第二个分组
result.groups()/result.groups(0) ('$22', '$33') 获取所有的分组
"""
点赞
收藏
评论区
推荐文章
半臻 半臻
4年前
Python基础11——正则表达式
19正则表达式19.1正则基础正则表达式:字符串处理工具应用场景1.html查询2.验证字符串是否符合规则re模块match方法python通过正则表达式对字符串进行匹配importre使用match方法进行匹配操作re.match()从字符串的开始位置进行匹配,匹配成功,返回match对象。匹配失败,返回Noneresre
Kubrnete Kubrnete
4年前
Python正则表达式
re正则表达式基础语法|表达式|可匹配|表达式|可匹配|||||||\r,\n|代表回车和换行符|\^|可匹配^本身||\t|制表符|\$|匹配$符号本身||\\|代表“\”本身|\.|匹配小数点“.”本身||表达式|可匹配|||||\d|任意一个数字,09中的任意一个||\
Wesley13 Wesley13
4年前
java RSA算法的性能记录
环境JavaHotSpot(TM)64BitServerVM1.7.0\_05x86\_64加密<table<tr<td内容长度</td<tdkeySize</td<td耗时(微秒)</td</tr<tr<td32</td<td512</td<td87</td</tr<tr<td
红烧土豆泥 红烧土豆泥
4年前
Java的数值数据类型以及命名规范
一、Java中的数值数据类型<table<tbody<tr<tdwidth"75"valign"top"style"wordbreak:breakall;"<spanstyle"backgroundcolor:rgb(255,254,213);"类型名<br</span</td<tdwidth"299
Stella981 Stella981
4年前
Jira 使用手册
<tablestyle"width:100%;margin:200px0300px0;"<tr<thDate</th<thRevisionversion</th<thDescription</th<thauthor</th</tr<tr<td20180614</td<tdV1.0.0</td
Stella981 Stella981
4年前
Bootstrap学习笔记
1.Table:table,tablebordered,table,tablehover,tablecondensed,2.tr,td:active,success,warning,danger,info3.Form:formgroupformcontrol,forminline,formhorizontal,4.
Wesley13 Wesley13
4年前
2020软件工程作业03
<styletable{width:100%;/\表格宽度\/margin:auto;/\外边距\/emptycells:show;/\单元格无内容依旧绘制边框\/fontsize:18px;}table,th,td{border:2pxsolidpink;}li{fontsize:1
Wesley13 Wesley13
4年前
MYSQL正则表达式
MySQL中使用REGEXP操作符来进行正则表达式匹配。下表中的正则模式可应用于REGEXP操作符中。模式描述^匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配'\\n'或'\\r'之后的位置。$匹配输入字符串的结束位置。如果设置了RegExp对象的Mul
Stella981 Stella981
4年前
Python 正则表达式规则
正则表达式的一些匹配规则:.:用于匹配任意一个字符,如a.c可以匹配abc、aac、akc等^:用于匹配以...开头的字符,如^abc可以匹配abcde、abcc、abcak等$:用于匹配以...结尾的字符,如abc$可以匹配xxxabc、123abc等\:匹配前一个字符零次或多次,如abc
Wesley13 Wesley13
4年前
Java 日期与时间
Java的日期Java没有内置的日期类,但可以导入java.time包,这个包中包含了许多类,可用于处理日期和时间。例如:<table<tbody<tr<thstyle"width:25%"Java类</th<thstyle"width:75%"描述</th</tr<tr<td<code
Stella981 Stella981
4年前
Linux文本处理常用命令
1.正则表达式(1)正则表达式一般用来描述文本模式的特殊用法,由普通字符(例如字符az)以及特殊字符(称为元字符,如/、\、?等)组成。(2)基本元字符集及其含义^:只匹配行首。 如^a匹配以a开头的行abc,a2e,a12,aaa,......$:只匹配行尾。 如^a匹配以a结尾的行bca,12a,