爬虫必备知识点---正则表达式---11.py

一、什么是正则表达式

        在实际开发过程中经常会有查找符合某些复杂规则字符串的需要,比如:邮箱、图片地址、手机号码等。

二、python使用正则表达式---re模块

        re模块提供了常见的正则匹配操作,如:匹配、搜索、替换等功能。

(一)、re里面的基本的方法

        匹配操作 re.match() 从字符串的开始进行匹配,如果开始部分匹配成功就返回匹配对象,否则返回None。

import re
re1 = re.match("python","python_one") # 从头开始匹配,有则匹配,并返回对象,无则返回None.
print(re1)
print("-"*12+"match"+"-"*12)
re2 = re.match("python","fpython_one") # 从头开始匹配,有则匹配,并返回对象,无则返回None.
print(re2)
print("-"*12+"match"+"-"*12)

        搜索操作 - re.search() re.search() 扫描字符串,如果找到匹配就返回匹配对象,否则返回None。从任意位置开始匹配。

# 这里出现了一个问题就是,re = re.match(),下一个re1 = re.match()就会报错,变量未被定义。
# 解决方案,取名不要和函数方法取一样的。
print("-"*12+"searchone"+"-"*12)
re_one = re.search("python","python_one") # 从任意位置匹配
print(re_one)
print("-"*12+"searchtwo"+"-"*12)
re_two = re.search("python","fpython_one")
print(re_two)

        提取操作  re.findall() 查找所有匹配,返回所有匹配结果的列表。文本1(.*?)文本2 ,这是非贪婪模式。有匹配的数据,返回的是列表,无,空列表。

# 提取操作 - re.findall() re.findall() 查找所有匹配,返回所有匹配结果的列表
string = "abcdefghijklmnopqrstuvwxyz1234567890"
find01 = re.findall("a(.*?)0",string)
print(find01)

print("-"*12+"findall_2"+"-"*12)
string2 = "abcdefghijklmnopqrstuvwxyz1234567890"
find02 = re.findall("a",string2)
print(find02)

        提取操作  re.finditer() 查找所有匹配,返回所有匹配结果的一个iterator(迭代器)。迭代器可以循环遍历得到。如下代码。

print("-"*12+"finditer"+"-"*12)
re_fi = re.finditer(pattern="python",string="pythonzzz")
print(re_fi)
for i in re_fi:
    print(i)
    print(i.group()) # 可以从迭代器遍历的对象里面找到匹配的内容。

        替换操作  re.sub() 用于替换匹配的字符串。将匹配到的字符串替换为另一个字符串。

string_before = "python,zhang,hudh"
string_now = re.sub("python","zzz",string_before)
print(string_before)  # 注意,这里不会改变原来的变量string_before,而是重新生成了一个对象储存
print(string_now)
# python,zhang,hudh
# zzz,zhang,hudh


print("-"*12+"re.sub"+"-"*12)

string_before = ["pythin","shfheu","python"]  # 为啥列表不可以----因为争对的是原字符串
string_now = re.sub("python","zzz",'string_before')
print(string_before)  # 注意,这里不会改变原来的变量string_before,而是重新生成了一个对象储存
print(string_now)
# ['pythin', 'shfheu', 'python']
# string_before

(二)、相关规则匹配单/多个字符---正则表达式介绍

        多数字、字母和符号会简单地匹配自身,但规则有例外,有些字符是特殊的,并不匹配自身。因为这些字符,有表达式中,有特殊的含义。如果想匹配这些内容,只需要在符号前上1个\就可以了,例如:匹配$, 就可以写成\$。

下面是需要加\的特殊字符

# . ^ $ * + ? { } [ ] \ | ( )

        规则,除了\t(1个制表)和\n(1个换行)匹配字符如下表格

代码功能
.匹配任意1个字符(除了\n)
[ ]匹配1个[ ]中列举的字符,例如[0-9a-zA-Z],[Hh],字符有其中的,都能匹配
\d匹配1个数字,即0-9
\D匹配1个非数字,即不是数字
\s匹配1个空白,即 空格,tab键
\S匹配1个非空白
\w匹配非特殊字符,即a-z、A-Z、0-9、_、汉字
\W

匹配特殊字符,即非字母、非数字、非汉字

*匹配0个或多个表达式
+匹配1个或多个表达式
()匹配()内的表达式,也表示一个组
*匹配前一个字符出现0次或者无限次,即可有可无
+匹配前一个字符出现1次或者无限次,即至少有1次
?匹配前一个字符出现1次或者0次,即要么有1次,要么没有
{m}匹配前一个字符出现m次
{m,n}匹配前一个字符出现从m到n次

        *

import re

ret = re.match("[A-Z][a-z]*","Q")
print(ret.group())

ret = re.match("[A-Z][a-z]*","ZvjA")
print(ret.group())

ret = re.match("[A-Z][a-z]*","Adjfff")
print(ret.group())
# Q 第一个字符必须是大写,第二字符是小写,且可有可无,但是后续有匹配的是小写的,因为*号前面就是小写的
# Zvj
# Adjfff

        +

import re

ret = re.match("[A-Z][a-z]+","Qm")
print(ret.group())  # Qm

ret1 = re.match("[A-Z][a-z]+","Q") # 原因在于+,至少要匹配一次,第一个字符必须是大写,第二字符必须是小写(至少匹配一次)单个Q匹配不到
# 第一个字符必须是大写,第二字符必须是小写,因为*,0次或多次,单个Q,也可以匹配,,因为*号前面就是小写的,后续有匹配的是小写的,都匹配得到
print(ret1.group())  # Traceback (most recent call last):
#   File "D:\python_env\Python_env2_spider\Lib\01_re正则表达式的学习\02_re_+.py", line 7, in <module>
#     print(ret1.group())
#           ^^^^^^^^^^
# AttributeError: 'NoneType' object has no attribute 'group'

        ?

import re


match_1 = re.match("zhangS?", "zhang")
# ?可匹配也可以不匹配S
print(match_1.group())
# zhang

        {} 

ret = re.match("[a-zA-Z0-9_]{5}","544432313")
print(ret.group())
ret = re.match("[a-zA-Z0-9_]{1,44}","15415751njjhbbjjnjhnjkjhb")
print(ret.group())
# 54443
# 15415751njjhbbjjnjhnjkjhb

(三)、贪婪模式和非贪婪模式

        那么贪婪模式和非贪婪模式的区别就是:

  • 贪婪模式:量词会尽可能多的匹配字符
  • 非贪婪模式:量词会尽可能少的匹配字符

        在正则表达式中,贪婪模式是默认的可以通过在量词后面加?(匹配0次或者1次)将其转换为非贪婪模式,爬虫中通常使用非贪婪模式。

moder1 = re.findall("<p>.+?</p>",d)
print(moder1)
print(1)
moder2 = re.findall("<p>.*?</p>",d)
print(moder2)  # ['<p>hdfufhfufdoff</p>', '<p>hyguff</p>']
moder3 = re.findall("<p>(.*?)</p>",d)
print(moder3) # ['hdfufhfufdoff', 'hyguff']

d = "<p>hdfufhfufdoff</p><p>hyguff</p>"
moder = re.match("<p>.+</p>",d)
print(moder.group())
moder1 = re.match("<p>.+?</p>",d)
print(moder1.group())

(四)、匹配开头和结尾,[^xxxx]取反

代码功能
^

匹配字符串开头   ^\d.+  数字开头的都可以匹配

$匹配字符串结尾  .+\d$   数字结尾都可以匹配
[^xxx]取反,[^asd].+ 表示后续的字符只要不是asd都可以匹配

(五)、或者与分组

代码功能
|匹配左右任意一个表达式         "python|c++" 
(ab)将括号中字符作为一个分组        "(163|qq|126)\.com"        \.是转义字符
\num引用分组num匹配到的字符串        
(?P<name>)分组起别名
(?P=name)引用别名为name分组匹配到的字符串

        |

import re
skill = ["python", "c", "c++", "java"]
# 遍历数据,变成字符对象,就可以用match了。
for i in skill:
  match_obj = re.match("python|html", i) #  |   匹配左右任意一个表达式
  if match_obj:
    print(f"{match_obj.group()}:yes")
  else:
    print(f"{i}:no")
# python:yes
# c:no
# c++:no
# java:no

        ()分组、\num ,\1 或者\\1 需要转义字符帮助,还有就是1代表的是第一个分组,输出第一个分组print(re_match.group(1))的内容。

import re
match_obj = re.match("<[a-zA-Z1-6]+>.*</[a-zA-Z1-6]+>", "<div>gtfdt</div>")
print(match_obj.group()) # <div>gtfdt</div>


match_obj = re.match("<([a-zA-Z1-6]+)>(.*)</\\1>", "<div>tfdt</div>")
print(match_obj.group()) # <div>tfdt</div>
print(match_obj.group(1)) # div
print(match_obj.group(2)) # tfdt

         (?P<name>)分组起别名

import re
match_obj = re.match("<[a-zA-Z1-6]+>.*</[a-zA-Z1-6]+>", "<div>gtfdt</div>")
print(match_obj.group()) # <div>gtfdt</div>


match_obj = re.match("<(?P<name1>[a-zA-Z1-6]+)>(.*)</(?P=name1)>", "<div>tfdt</div>")
print(match_obj.group()) # <div>tfdt</div>
print(match_obj.group(1)) # div
print(match_obj.group(2)) # tfdt

(六)、Python的re模块支持以下5种标志:

        注意:re.match("pattern","string","flags" ) 这里的flags为python中的编译标注位,用于修改正则表达式的匹配方式。例如:re.match("pattern","string",re.S )

代码功能
re.I(IGNORECASE)忽略大小写,使匹配对大小写不敏感
re.M(MULTILINE)多行匹配,修改'^'和'$'的行为
re.S(DOTALL).可以匹配所有字符,包含换行符
re.U(UNICODE)使用Unicode匹配
re.X(VERBOSE)忽略空格和注释,使正则表达式更具有可读性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

要争就争第一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值