【爬虫基础】正则表达式和re模块

什么是正则表达式

正则表达式语法

单字符串匹配

  • 使用元字符匹配单个字符
字符功能
.匹配任意一个字符(除了\n)
[]匹配[]中列举的字符
\d匹配数字
\D匹配非数字
\s匹配空白(空格,\n,\r, \t)
\S匹配非空白
\w匹配单词字符
\W匹配非单词字符
*匹配前一个字符出现0次或无次,即可有可无
+匹配前一个字符出现1次或无限次,即至少有1次

匹配多个字符串

  • 数量词
  • 使用数量词匹配多个字符
字符功能
{m}匹配前一个字符出现m次
{m,n}匹配前一个字符出现m到n次
# 匹配QQ号码,5~12位,不能是0开头
import re
lis = ['012345@qq.com', '1234@qq.com', '11234@qq.com', '123452@qq.com','123456@qq.com','23564827@qq.com',]
for li in lis:
    m = re.match('[1-9][0-9]{4,11}', li)
    if m:
        print(m.group())
    else:
        print(li, "错误的QQ号码")

精确匹配与泛匹配

  • 泛匹配时匹配所有的东西
  • 精确匹配是匹配括号里的东西
import re
str = 'python 1234 slkjfgi 4567, hello'
pattern = 'python.*hello'
res = re.findall(pattern, str)
print(res)  # ['python 1234 slkjfgi 4567, hello']
pattern = 'python.(\d+).*hello'
res = re.findall(pattern, str)
print(res)  # ['1234']

贪婪匹配与非贪婪匹配

  • python中数量词默认是贪婪的(在少数语言中也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪相反,总是尝试匹配尽可能少的字符。
  • 在 * ,?, + ,{m,n} 后面加上?,使贪婪变成非贪婪。
import re
str = 'python 1234 slkjfgi 4567, hello'

pattern = 'python.(\d+?).*hello'
res = re.findall(pattern, str)
print(res)  # 1 符合条件就停止匹配

pattern = 'python.(\d+).*hello'
res = re.findall(pattern, str)
print(res)  # 1234  在符合条件下尽可能匹配更多

开始和结束语法

字符含义
^以…开头
$以…结尾
import re
lis = ['123456@163.com', '98765@163.com', '@abcd@163.com', '1234@163.comhol']

for li in lis:
    m = re.match('\d*@163\.com', li)
    if m:
        print(li, "符合邮箱规定,匹配后是", m.group())
    else:
        print(li, '不符合邮箱规定')
print("="*50)
for li in lis:
    m = re.match('^\d*@163\.com$', li)  # 必须以数字开头,以 @163.com 结尾
    if m:
        print(li, "符合邮箱规定,匹配后是", m.group())
    else:
        print(li, '不符合邮箱规定')

在这里插入图片描述

转义字符和原生字符串

  • python中字符串前面加上 r 表示原生字符串
  • 与大多数编程语言相同,正则表达式里使用" \ “作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符”“,那么使用编程语言表示的正则表达式里将需要四个反斜杠’” \ ":前两个和后两个分别用在编程语言里转译成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。
  • python里的原生字符串很好的解决了这个问题,有了原生字符串,写出来的表达式更加直观。
import re
m = "c:\\a\\b\\c"
print(m)  # c:\a\b\c
res = re.match("c:\\\\a", m).group()
print(res)  # c:\a
res = re.match(r"c:\\a", m).group()
print(res)  # c:\a

re模块中常用函数

match

  • 用于查找字符串的头部(也可以指定起始位置),它是一次匹配,也就是说找到了一个结果就返回,而不是查找所有匹配的结果。一般使用形式如下:
# match(pattern, string[,flag])
import re
# 正则
pattern = 'python'
# 字符串
string = 'pythonalkjgoaija'
res = re.match(pattern, string)
print(res)  # 匹配成功返回一个match对象,失败返回None

search

  • 用于查找字符串的任何位置,它也是一次匹配

group分组

  • 返回一个或多个匹配的字串。如果只有一个参数,结果只有单个字符串;如果有多个参数,结果是一个元组,元组里每一项对应一个参数。没有参数,group1默认是0(整个匹配串被返回)。如果groupN参数是0,对应的返回值是整个匹配串;如果它属于[1,99],返回对应的一项括号分隔的群。如果参数是负数或大于模式串中定义的群数,IndexError异常会被抛出。如果模式串没有任何匹配,group返回None;如果模式串多次匹配,group将返回最后一次匹配。
import re
m = re.match(r"(\w+) (\w+)", "python hello, abcd")
print(m.group())  # python hello
print(m.group(0))  # python hello
print(m.group(1))  # python
print(m.group(1, 2))  # ('python', 'hello')

findall

  • 搜索整个字符串,获得所有匹配结果。一列表形式返回匹配所有匹配结果,如果没有则返回一个空列表
import re
ret = re.findall(r'\d+', 'ljllajl123, 456,$%++09')
print(ret)
  • 参数flags
符号含义
re.l使匹配对大小写不敏感
re.L做本地化识别(locale-aware)匹配
re.M多行匹配,影响 ^ 和 $
re.S使 . 匹配包括换行在内的所有字符
re.U根据Unicode字符集解析字符,影响 \w, \W, \b, \B
re.X该标志通过给予你更灵活的格式以便于你将正则表达式写的更易于理解

sub

  • 替换
# sub(pattern, repl, string[, count,flags])
# pattern: 正则
# repl: 要替换的字符串
# string: 待替换的字符串
# count: 替换次数
import re
pattern = 'java'
repl = 'python'
string = 'java 十分简单, java是世界上最好的语言'
res = re.sub(pattern, repl, string)
print(res)

split

  • 按照匹配的子串将字符串分割后返回列表
import re
# split(pattern, string[, maxsplit, flags])
# maxsplit:默认是0,表示全部切割,1代表切一次,2代表切两次
# 切割去掉了匹配到的字符串
import re
ret = re.split(r'\d+', 'ljllajl123$456$%++09', 2)
print(ret)

compile

  • 将正则表达式的字符串编译成一个pattern对象。通过该对象提供的一系列方法对文本进行匹配查找,获得匹配对象。编译可以实现更高效的匹配查找。
import re
# 将正则表达式编译成Pattern对象
pattern = re.compile('\d+', re.S)
# 编译成pattern对象后可以复用该模式
res = re.findall(pattern, 'asdklfj123lk')
res2 = re.findall(pattern, '12345@qq.com')
res3 = re.findall(pattern, '158*****0709')
print(res,res2,res3)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值