python正则表达式

正则表达式

视频链接:
https://www.bilibili.com/video/BV1q4411y7Zh

在线验证网站:
https://regex101.com

一个例子

import re

text = '''
Python3 高级开发工程师 上海胡椒教育科技有限公司上海-浦东新区2万/月02-18满员
测试开发工程师(C++/Python) 上海默契数码科技有限公司上海-浦东新区2.5万/每月02-18未满员
Python3 开发工程师 上海胡椒教育科技有限公司上海-浦东新区2万/月02-18满员
测试开发工程师(C++/Python) 上海默契数码科技有限公司上海-浦东新区1.3万/每月02-18未满员
Python 高级开发工程师 上海上向科技有限公司上海-浦东新区2万/月02-18剩余255人
测试开发工程师(Java/Python) 上海新其数码科技有限公司上海-浦东新区1.1万/每月02-18未满员
'''
p = re.compile(r'([\d.]+)万/每?月')
# p = re.compile(r'([\d.]+)万/每{0,1}月')
print(p.findall(text))

常见语法

  • 普通字符如汉字和英语字符可以直接匹配,
  • 元字符(metacharacters),元字符表示一些特殊的含义

这些特殊的字符包括:

. * + ? \ [ ] ^ $ { } | ()
  1. .表示除了换行符之外的任何单个字符
    (也就是默认以行为单位匹配)

    比如,要从下面文本中选择出所有的颜色

苹果是绿色的
大菠萝是黄色的
香蕉是黄色的
乌鸦是黑色的

也就是找到所有以“色”结尾,并且包括前面一个字符的词语,也就可以写成.色

  1. *表示匹配前面的子表达式任意次数,包括0次,
    比如,你想匹配下面字符串中逗号后面的字符内容,包括括号本身
苹果,是绿色的
橙子,是橙色的
香蕉,是黄色的
乌鸦,是黑色的
猴子,是
  1. +表示匹配前面的字符,至少要出现一次
  2. {}表示匹配前面的字符指定次数
红彤彤,绿油油,黑乎乎
油{1,2}

贪婪匹配与非贪婪匹配

import re

source = '<html><head><title>Title</title>'
p = re.compile(r'<.*>')
print(p.findall(source))
print('👆RE中" * + ?"会默认贪婪匹配,尽可能多(长)的去匹配')
print('现在想要尽可能短的去匹配,可以使用非贪婪模式,也就是在星号或者加号后面加上?<.*?>')
p = re.compile(r'<.*?>')
print(p.findall(source))

反斜杠

利用反斜杠\转移特殊字符.

苹果.是绿色的
橙子.是橙色的
香蕉.是黄色的
import re

p = re.compile(r'.*\.')

此外,反斜杠\也可以表所匹配某种类型的一个字符,比如

转义字符 等价的表达式
\d 匹配0-9之间的任意一个数字字符 [0-9]
\D 匹配任意一个不是0-9之间的数字字符 [^0-9]
\s 匹配任意一个空白字符,包括空格,tab,换行符 [\t\n\r\f\v]
\S 匹配任意一个非空白字符 [^\t\n\r\f\v]
\w 匹配任意一个文字字符,包括大小字母,数字,下划线(缺省情况下也包含Unicode字符汉字和abc等)) [a-zA-Z0-9]
\W 匹配任意一个文字字符 [^a-zA-Z0-9]

Tips: 反斜杠也可以用在方括号里面

匹配有效的电话号码

假设以13、或者15开头的后面跟着连续9个数字的才是有效的电话号码

王雅虎,13500344799,89
徐志摩,1b900785634,23
周根源,15909875678,44
周根原,17909875678,44
好运莫,05900785634,24
李根源,23909875678,44

利用方括号[]代表候选字符,里面可以使用-表示范围,,表示可选元素

import re

text = '''
王雅虎,13500344799,89
徐志摩,1b900785634,23
周根源,15909875678,44
周根原,17909875678,44
好运莫,05900785634,24
李根源,23909875678,44'''
p = re.compile(r'1[3,5]\d{9}')
# p = re.compile(r'1[3-7]\d{9}')
print(p.findall(text))

Tips:

  • 反斜杠也可以用在方括号[]里,比如\s代表空白字符,
  • 需要注意的是,一些元字符在方括号里面失去了魔法,变得和普通字符一样了
    比如,[akm.]表示匹配a k m .中的任意一个字符,.不代表任意字符了
  • 如果,方括号中使用^,表示方括号里面的所有的字符集合

文本的位置

^除了在[]表示的概念,也表示文本的起始位置
正则表达式,可以分成单行模式和多行模式,其中

  • 单行模式表示匹配整个文本的开头位置
  • 多行模式表示匹配文本每行的开头位置
001-苹果价格-50
002-橙子价格-70
003-香蕉价格-80
import re

text = '''001-苹果价格-50
002-橙子价格-70
003-香蕉价格-80'''
p = re.compile(r'\d+')
print(p.findall(text))
print('只要编号,而且开启多行模式(python默认单行)')
p = re.compile(r'^\d+', re.MULTILINE)
print('编号', p.findall(text))
p = re.compile(r'\d+$', re.M)
print('价格:', p.findall(text))

$表示文本的结尾,与^用法大体相同

括号-组选择

括号称之为正则表达式的组选择。是从正则表达式 匹配的内容里面 扣取出其中某些部分
(声明我们所感兴趣的区域)

前面,我们有一个例子,从下面文本中,选择每行逗号前面的字符串,也包括了逗号本身。

苹果,苹果是绿色的
橙子,橙子是橙色的
香蕉,香蕉是黄色的

我们前面正则表达式写法是^.*,
但是如果我们 不要逗号呢。
当然不能写作^.*,因为逗号是特征所在,
如果去掉它就没法找逗号前面的了。
但是如果放在正则表达式里面,找到的结果又会包含逗号,
解决的办法就算使用括号-组选择器

import re

text = '''苹果,苹果是绿色的
橙子,橙子是橙色的
香蕉,香蕉是黄色的'''
p = re.compile(r'^(.*),', re.M)
print('找到逗号前面的内容且返回内容不包括逗号:', p.findall(text))
print('如果感兴趣的有多组:')
text = '''章三,手机号码15088511575
章四,手机号码15088511575
章五,手机号码15088511575'''
p = re.compile(r'(^.+),.+(\d{11})', re.M)
print('如果感兴趣的有多组(有多个括号):对自动组成元组', p.findall(text))

切割字符串

用字符串的split()函数可很方便的切割字符串,但在某些时候不够用

import re

names = '关羽; 张飞, 赵云, 马超, 黄忠 李逵'
# 方括号代表任意选一种
# 分割符为分好、逗号,空格的任意一种,并且该符号周围可以有不定数量的空格
namelist = re.split(r'[;,\s]\s*', names)
print(namelist)

替换

import re

text = '''<a href='https://www.bilibili.com/video/av1/?p=1'>点击</a>
<a href='https://www.bilibili.com/video/av2/?p=10'>点击</a>
<a href='https://www.bilibili.com/video/av3/?p=10'>点击</a>

'''


def sub_func(match: re.Match):
    # Match对象的 group(0)返回的是整个匹配上的字符串
    src = match.group(0)
    # Match对象的group(1),第一个group的内容
    number = int(match.group(1)) + 10
    dst = f'/av{number}'
    print(f'{src}替换为{dst}')
    # 返回值就是最终替换的字符串
    return dst


newStr = re.sub(r'/av(\d+?)/', sub_func, text)
print(newStr)

Search和Match和索引

  • re.match()仅在字符串的开头匹配
  • re.search()在字符串中的任何位置检查匹配项。
import re

p = re.compile(r'\w+')
print(p.search('abcde').group())
p = re.compile(r'a')
print(p.search('abcade').group())
# 同search,不过在字符串开始处进行匹配,只会匹配一个对象
print(p.match('abcade').group())
print('索引:', p.search('abcade').start(), p.search('abcade').end())
posted @   白柒  阅读(60)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示