个人笔记——正则表达式

本文详细介绍了Python中正则表达式的使用,包括匹配单个和多个字符、组合匹配、开头结尾匹配、分组以及re模块的高级用法如search、findall、sub和split。同时展示了如何运用正则表达式进行网页模板清洗。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

正则表达式

一般使用re模块

匹配单个字符

字符功能
.匹配任意一个字符(除了\n)
[ ]匹配[ ]中列举的字符,连续的可以用-连接,如:[1-8]
\d匹配数字,即0-9
\D匹配非数字
\s匹配空白,即空格、Tab
\S匹配非空白
\w匹配单词字符,即a-z、A-Z、0-9、_
\W匹配非单词字符

例:

>>ret = re.match(r"速度与激情\d", "速度与激情5")
>>ret.group()
>速度与激情5

匹配多个字符

字符功能
*匹配前一个字符出现0次或者无限次,即可有可无
+匹配前一个字符出现1次或者无限次,即至少1次
?匹配前一个字符出现1次或者0次,即要么有1次,要么没有
{m}匹配前一个字符出现m次
{m, n}匹配前一个字符出现m到n次 切记!逗号后面不要加空格!!!

例:

import re

names = ["name1", "_name", "2_name", "__name__"]

for name in names:
    ret = re.match("[a-zA-Z_]+[\w]*", name)
    if ret:
        print("变量名 %s 符合要求" % ret.group())
    else:
        print("变量名 %s 非法" % name)
>>变量名 name1 符合要求
变量名 _name 符合要求
变量名 2_name 非法
变量名 __name__ 符合要求

组合

*?:重复任意次,但尽可能少重复
例:

>>re.match(r"a.*?b", "acbacb")
>acb

+?:和上面一样,只不过至少重复一次
??:重复0次或1次,但尽可能少
例:

>>re.match(r"a.??b", "aaaacb")
>acb

匹配开头结尾

字符功能
^匹配字符串开头
$匹配字符串结尾
import re

def main():
    names = ["age", "_age", "1age", "age1", "a_age", "age_1_", "age!", "a#123", "_____"]
    for name in names:
        ret = re.match("^[a-zA-Z_][a-zA-Z0-9_]*$", name)
        if ret:
            print("变量名:%s 符合要求...通过正则匹配出来的数据时:%s" % (name, ret.group()))
        else:
            print("变量名:%s 不符合要求" % name)


if __name__ == "__main__":
    main()
>>变量名:age 符合要求...通过正则匹配出来的数据时:age
变量名:_age 符合要求...通过正则匹配出来的数据时:_age
变量名:1age 不符合要求
变量名:age1 符合要求...通过正则匹配出来的数据时:age1
变量名:a_age 符合要求...通过正则匹配出来的数据时:a_age
变量名:age_1_ 符合要求...通过正则匹配出来的数据时:age_1_
变量名:age! 不符合要求
变量名:a#123 不符合要求
变量名:_____ 符合要求...通过正则匹配出来的数据时:_____

匹配分组

字符功能
(ab)将括号中字符作为一个分组
\num引用分组num匹配到的字符
(?P<name>)分组起别名
(?P=name)引用别名为name分组匹配到的字符串
例:和(ab)组合使用
>>re.match(r"[a-zA-Z0-9]{4,20}@(163|126).com", "laowang@126.com").group()
'''如果输入的值通过,则后续还可以取出()内的值来进行分析,如下'''
>>re.match(r"[a-zA-Z0-9]{4,20}@(163|126).com", "laowang@126.com").group(1)
>126
>>re.match(r"([a-zA-Z0-9]{4,20})@(163|126).com", "laowang@126.com").group(1)
>laowang
>>re.match(r"([a-zA-Z0-9]{4,20})@(163|126).com", "laowang@126.com").group(2)
>126

例:\num可以引用之前使用了()定义的分组

>>re.match(r"<(\w*)>.*</\1>", "<h1>hahahaha</h1>").group()
><h1>hahahaha</h1>

例:(?P<name>)与(?P=name)

>>html_str = '<body><h1>hahaha</h1></body>'
>>re.match(r"<(?P<p1>\w*)><(?P<p2>\w*)>.*</(?P=p1)></?P=p2>", html_str).group()
><body><h1>hahaha</h1></body>

re的高级用法

之前提及的正则表达式是包括Python和其他语言通用的,下面是Python独有的

search

例:

>>ret = re.search(r"\d+", "阅读次数为 9999")
>>ret.group()  # 只能提取第一个
>9999

findall

与search相比就在于能提取所有符合的字符
例:

>>ret = re.findall(r"\d+", "python = 999, c = 7890, c++ = 12345")
>>print(ret)
>['999', '7890', '12345']

sub

将匹配到的数据进行替换

>>re.sub(r"\d+", "996", "python = 997")
>python = 996

>>re.sub(r"\d+", "996", "python = 997, c++ = 1024")
>python = 996, c++ = 996

sub还支持函数
例:

def add(temp):
	strNum = temp.group()
	num = int(strNum) + 1
	return str(num)
ret = re.sub(r"\d+", add, "python = 997")
print(ret)
>998

split

根据匹配切割字符串,并返回一个列表
例:

ret = re.split(r":| ", "info = xiaoZhang 33 shandong")  # 根据:或者空格进行切割
print(ret)
>[info, xiaoZhangm,33, shandong]

清洗网页模板

# 清洗HTML标签文本
# @param htmlstr HTML字符串.
def filter_tags(htmlstr):
    # 过滤DOCTYPE
    htmlstr = ' '.join(htmlstr.split()) # 去掉多余的空格
    re_doctype = re.compile(r'<!DOCTYPE .*?> ', re.S)
    s = re_doctype.sub('',htmlstr)
    # 过滤CDATA
    re_cdata = re.compile('//<!CDATA\[[ >]∗ //\] > ', re.I)
    s = re_cdata.sub('', s)
    # Script
    re_script = re.compile('<\s*script[^>]*>[^<]*<\s*/\s*script\s*>', re.I)
    s = re_script.sub('', s)  # 去掉SCRIPT
    # style
    re_style = re.compile('<\s*style[^>]*>[^<]*<\s*/\s*style\s*>', re.I)
    s = re_style.sub('', s)  # 去掉style
    # 处理换行
    re_br = re.compile('<br\s*?/?>')
    s = re_br.sub('', s)     # 将br转换为换行
    # HTML标签
    re_h = re.compile('</?\w+[^>]*>')
    s = re_h.sub('', s)  # 去掉HTML 标签
    # HTML注释
    re_comment = re.compile('<!--[^>]*-->')
    s = re_comment.sub('', s)
    # 多余的空行
    blank_line = re.compile('\n+')
    s = blank_line.sub('', s)
    # 剔除超链接
    http_link = re.compile(r'(http://.+.html)')
    s = http_link.sub('', s)
    return s
​
# 正则处理html网页数据
s=filter_tags(str_doc)
print(s)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值