Python正则表达式知识总结完整版

正则表达式

相信大家在学习爬虫时,经常会遇到正则表达式匹配字符问题,最近我对于这方面知识的学习,总结全部整理如下:

一. 概述

正则表达式,又称正规表达式、规则表达式(英语:Regular Expression,在代码中简写为regex、regexp或者RE),是计算机科学的一个概念;也就是用来描述、匹配一系列某个句法规则的字符串。

Regular Expression就是描述某种规则的表达式的意思。

二. re模块操作

1. re模块的使用
#coding=utf-8
# 导入re模块
import re

# 使用match方法进行匹配操作
result = re.match(正则表达式,要匹配的字符串)

# 如果上一步匹配到数据的话,可以使用group方法来提取数据
result.group()

re.match是用来进行正则匹配检查的方法,若字符串匹配正则表达式,则match返回匹配对象(Match Object),否则返回None。

match方法是从左到右进行匹配的

匹配到对象Match Object具有group方法,用来返回字符串的匹配部分。

2. re模块示例
#coding=utf-8

import re

result = re.match("itcast", "itcast.cn")

result.group()

运行结果:‘itcast’

三. 表示字符

正则表达式的单字符匹配:
字符功能
.匹配任意1个字符(\n)
[ ]匹配[ ]中列举的字符
\d匹配数字,即0-9
\D匹配非数字,即不是数字
\s匹配空白,即空格, tab键
\S匹配非空白
\w匹配单词字符,即a-z、A-Z、0-9、…
\W匹配非单词字符

示例1:手机号校验

re.match("1\d\d\d\d\d\d\d\d\d\d\d", 1234)

re.match(“1[34578]” , “18”)
re.match(“1[34578]” , “19”)

^号表示取反
re.match(“1 [^34578]”, “19”)
re.match(“1 [^34578]” , “1a”)

  • 号表示范围的意思
    re.match(“1[a-z5-9” , “11”)
    re.match(“1[a-z5-9]”, “19”)
    -------------------------------即
    \d == [0-9]
    \D == [^0-9]
    \w == [a-zA-Z0-9_]

四、表示数量

字符功能
*匹配前一个字符出现0次或者无限次,即可有可无
+匹配前一个字符出现1次或者无限次,即至少有1次
匹配前一个字符出现1次或者0次,即要么有1次,要么没有
{m}匹配前一个字符出现m次
{m,}匹配前一个字符至少出现m次
{m, n}匹配前一个字符出现从m到n次

“ * ”号
re.match("\d*", " “)
re.match(”\d*" , “abc”)
re.match("\d*" , “123”)
" + " 号
re.match("\d+" , “1”)
re.match("\d+" , “abc”)不匹配
re.match("\d+" , “123abc”)
" ? " 号
re.match("\d?" , “abc”)
re.match("\d?" , “1abc”)
re.match("\d?" , “1234abc”)注意这是匹配的

re.match("\d{4} [a-z]" , “1234abc”)
re.match("\d{3} [a-z]" , “1234abc”)不匹配
re.match("\d{5} [a-z]" , “1234abc”) 不匹配

故然:
\d{1, } == \d+
\d{0, } == \d*
\d{0,1} == \d?

示例2:

s = “\nabc”
print s
: abc

正确匹配应为:
s = “\nabc”
: \nabc

或者加 r 转义不让\n表示换行:
s = r"\nabc"
: \nabc
要习惯性加 r ,防止转义

五、表示边界

字符功能
^匹配字符串开头
$匹配字符串结尾
\b匹配一个单词的边界
\B匹配非单词边界
示例:\B

re.match(r".*\Bver\B" , “hoverabc”).group()
‘hover’

re.match(r".*\Bver\B" , “ho verabc”).group()
不匹配

re.match(r".*\Bver\B" , “hover abc”).group()
不匹配

re.match(r".*\Bver\B" , “ho ver abc”).group()
不匹配

六、匹配分组(扩展部分)

字符功能
匹配左右任意一个表达式
(ab)将括号中字符作为一个分组
\num引用分组num匹配到的字符串
(?P)分组起别名
(?P=name)引用别名为name分组匹配到的字符串
示例:

需求:匹配出0-100之间的数字

#coding=utf-8
import re

ret = re.match("[1-9]?\d", "8")
ret.group()

ret = re.match("[1-9]?\d", "78")
ret.group()

# 不正确的情况
ret = re.match("[1-9]?\d", "08")
ret.group()

# 修正后的
ret = re.match("[1-9]?\d$", "08")

# 加入边界及特殊情况0和100
ret = re.match("[1-9]\d?$|0$|100$", "100"

七、re模块的高级用法

search

需求:匹配出文章阅读的次数

#coding=utf-8
import re

ret = re.search(r"\d+", "阅读次数为 9999“)
ret.group()

运行结果:

‘9999’

findall

需求:统计出python、c、c++相应阅读文章的次数

#coding=utf-8
import re

ret = re.findall(r"d+", "python = 9999, c = 7890, c++ = 8977")
print ret

运行结果:

[‘9999’, ‘7890’, ‘9877’]

sub 将匹配到的数据进行替换

需求:将匹配到的阅读次数加1
方法1:

#coding=utf-8
import re

ret = re.sub(r"\d+", '998', "python = 997")
print ret

运行结果:
python = 998

In:re.sub(r"php", “python”, “itcast python cpp php python php”)
Out:‘itcast python cpp python python python’
In:re.sub(r"\d+", “50”, “python=1000, php=0”)
Out:’python=50, php=50’

In:def replace(result):
print(result.group())
return “50”
In:re.sub(r"\d+", replace, “python=1000, php=0”)
Out:‘python=50,php=50"

In:def replace(result):
print(result.group())
r = int(result.group()) + 50
return str®
In:re.sub(r"\d+", replace, “python=1000, php=0”)
1000
0
Out:’python=1050, php=50"

注意: 正则表达式默认使用贪婪模式。

split 根据匹配进行切割字符串,并返回一个列表

需求:切割字符串“info:xiaoZhang 33 shandong"

#coding=utf-8
import re

ret = re.split(r":| ","info:xiaoZhang 33 shandong")
print ret

运行结果:
[ ‘info’, ‘xiaoZhang’, ‘33’, ‘shandong’ ]

python贪婪与非贪婪模式

Python里数量词默认是贪婪的,总是尝试匹配尽可能多的字符;

非贪婪相反,总是尝试匹配尽可能少的字符。

在“*”,“?”,“+”,“{m,n}”后面加上?,使贪婪变成非贪婪。

In: s=“This is a number 234-235-22-423”
In: r = re.match(r".+(\d±\d±\d±\d+)", s)
In: r.group(1)
Out: ‘4-235-22-423’

In: r = re.match(r"(.+)(\d±\d±\d±\d+)", s)
Out: (‘This is a number 23’, ‘4-235-22-423’)

In: r = re.match(r"(.+?)(\d±\d±\d±\d+)", s)
In: r.groups()
Out: ('This is a number ’ , ‘234-235-22-423’)

即:用?关掉贪婪模式。

小试牛刀

1. 匹配网址:

https://baike.baidu.com/item/%E7%89%9B/2620519?fr=aladdin
https://hanyu.baidu.com/zici/s?wd=%E7%9C%BC&query=%E7%9C%BC&srcid=28232&from=kg0
https://baike.baidu.com/item/%E7%9C%BC%E7%9D%9B/362?fr=aladdin
http://xh.5156edu.com/html3/14912.html

正则后需要为:

https://baike.baidu.com/
https://hanyu.baidu.com/
https://baike.baidu.com/
http://xh.5156edu.com/

s = "https://baike.baidu.com/item/%E7%89%9B/2620519?fr=aladdin"
# 使用lambda函数返回第一个括号内,即网址的地址
re.sub(r"http://.+?/).*", lambda x: x.group(1), s)
2. 找出单词

有一句英文如下:
hello world ha ha
查找所有的单词

s = "hello world ha ha"
# 从分隔符角度
re.split(r" +", s)

# 描述单词特征的角度
re.findall(r"\b[a-zA-Z]+\b", s)

END.

路在脚下,志在远方!继续向前吧~
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值