第四阶段 -- python核心特性:【正则表达式】

正则表达式–掘金博客

正则表达式不要背–掘金博客

【正则表达式可视化:regexper.com

Quick-Start: Regex Cheat Sheet】https://www.rexegg.com/regex-quickstart.html#logic

1. 正则表达式概述

  1. 概念:正则表达式是对字符串进行操作的一种逻辑公式,就是用事先定义好的一些特定的字符,以及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过来逻辑(可以用来检索,截取或者替换操作)。
  2. 简介:正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,模式描述在搜索文本时要匹配的一个或多个字符串
  3. 作用:
    • 1.给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”)
    • 2.可以通过正则表达式,从字符串中获取我们想要的特定部分。
    • 3.还可以对目标字符串进行替换操作

2. re模块之match的基本使用

  1. 语法:result = re.match(pattern, string, flags=0)
  • 从左到右依次进行匹配,则返回相应的match对象。如果字符串不匹配模式,返回None
  • pattern :匹配的正则表达式
  • string:要匹配的字符串
  • flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等。
  1. 用法:
  • group()方法:用来返回字符串的匹配部分
  • span()方法:返回匹配字符串的位置(元组存储开始,结束位置)
  • start()end()方法:存储匹配数据的开始和结束位置。(也可以通过对象的dir(对象查看对象的方法))
  • 注意:如果想在目标字符串的任意位置查找,需要使用search。
import re
pattern = 'hello'
s = 'helloworld' 
v = re.match(pattern, s) # 注意区分大小写!
print(v)
print(type(v))
print(dir(v))
print(v.group()) # 找到里面匹配的内容
print(v.span()) # 匹配内容的位置

##################

s1 = 'Helloworld hello'
v1 = re.match(pattern, s1)
# v = re.match(pattern, s1) # 找不到!因为re.match只能从开头开始查找
v = re.search(pattern, s1)
print(v)
print(type(v))
print(dir(v))
print(v.group())
print(v.span())

3. 匹配字符

  • 语法格式:
字符功能
.匹配任意一个字符(除了\n)
[]匹配列表中的字符
\d匹配一个数字,即0-9
\D匹配一个非数字
\s匹配一个空白、即空格(\n,\t)
\S匹配一个非空格
\w匹配一个单词字符,即a-z, A-Z, 0-9, _
\W匹配一个非单词字符
  • 举例:
import re
# '.'的验证
pattern = '.'
s = 'a'
s = 'A'
s = '0'
s = '_'
s = '\n'
v = re.match(pattern,s)
print(v)
import re
# '\d'与\D的验证
pattern = '\d'
pattern = '\D'
s = '0'
s = '9'
s = 'a'
s = '_'
v = re.match(pattern,s)
print(v)
import re
# '\s与\S的验证'
pattern = '\s'
pattern = '\S'
s = ' '
s = '\t'
s = '\n'
s = 'a'
v = re.match(pattern,s)
print(v)
import re
# '\w与\W的验证'
pattern = '\w'
pattern = '\W'
s = 'a'
s = 'A'
s = '0'
s = '_'
s = '-'
v = re.match(pattern,s)
print(v)
import re
# []的验证
pattern = '[13578]'
s = '1'
s = '3'
s = '5'
s = '7'
s = '8'
v = re.match(pattern,s)
print(v)
import re
# 匹配手机号的话 11位数
pattern = '1[35789]\d\d\d\d\d\d\d\d\d'
# s = '13812341234'
# s = '23812341234'
s = '15812341234'
v = re.match(pattern,s)
print(v)

4. 表示数量

  • 语法:
字符功能
*匹配前一个字符出现0次或者无限次(可有可无)
+匹配前一个字符出现1次或者无限次(至少有1次)
匹配前一个字符串出现1次或者0次(要么1次要么没有);非贪婪模式
{m}匹配前一个字符出现m次
{m,}匹配前一个字符至少出现m次
{m,n}匹配前一个字符出现m到n次
import re
# '*'的使用
pattern = '\d*'
s = '123abc'
s1 = 'abc'
v = re.match(pattern,s)
print(v)
v1 = re.match(pattern,s1)
print(v1)
import re
# '+'的使用
pattern = '\d+'
s = '123abc'
s1 = 'abc'
v = re.match(pattern,s)
print(v)
v1 = re.match(pattern,s1)
print(v1)
import re
# '?'的使用  表示可有(只出现一次)可无(0次)
pattern = '\d?'
s = '123abc'
s1 = 'abc'
v = re.match(pattern,s)
print(v)
v1 = re.match(pattern,s1)
print(v1)
import re
# '{m}'的使用,匹配前一个字符出现m次
pattern = '\d{2}'
# pattern = '\d{2,4}'
# pattern = '\d{3,}'
s = '12345678abc'
v = re.match(pattern,s)
print(v)

  • 例子:匹配出一个字符串首字母为大写字符,后边都是小写字符,这些小写字母可有可无;匹配出有效的变量名 变量名: 大写字母,小写字母,数字,下滑线
import re
# 匹配出一个字符串首字母为大写字符,后边都是小写字符,这些小写字母可有可无
pattern = '[A-Z][a-z]*'
s = 'Hello'
s = 'HEllo'
v = re.match(pattern,s)
print(v)

print('--------------------------------------------')

# 匹配出有效的变量名 变量名: 大写字母,小写字母,数字,下滑线
pattern = '[A-Za-z_][A-Za-z0-9_]*'
pattern = '[A-Za-z_]\w*'
s = 'Ab2_'
s = '2c'
s = '_2c'
v = re.match(pattern,s)
print(v)
  • 例子:匹配出1-99之间的数字
import re
# 匹配出1-99之间的数字
pattern = '[1-9][0-9]?'
# s = '0'
s = '10'
s = '99'
v = re.match(pattern,s)
print(v)
  • 例子:匹配出一个随机密码8-20位以内 {8,20} 大写字母小写字母,数字,下滑线
import re
# 匹配出一个随机密码8-20位以内 {8,20}  大写字母小写字母,数字,下滑线
pattern = '\w{8,20}'
s = 'abc123_123'
v = re.match(pattern,s)
print(v)

5. 原始(原生)字符串

  • 定义:python中字符串前面加上r你安表示原生字符串

    • 示例:
      • s = '\n123':换行
      • 方法一 使用\\s='\\n123':没有换行
      • 方法二 使用原生字符串:s = r'\n123':没有换行

    相关资料:【Python正则表达式匹配反斜杠“\”

  • 正则中的使用:

s = '\n123'
print(s)
s = r'\n123'
print(s)
# s = '\\n123'
# print(s)
# pattern = '\\\\n\d{3,}'
pattern = r'\\n\d{3,}'
v = re.match(pattern,s)
print(v)

6. 锚点 anchor

  • 语法及意义:
字符功能
^匹配字符串开头 。r'^a':以a开头
$匹配字符串结尾
\b匹配一个单词的边界
\B匹配非单词的边界
  • 案例:

    • 匹配QQ邮箱 &
    import re
    #匹配qq邮箱,  5-10位
    pattern = '[\d]{5,10}@qq.com'
    #必须限制结尾的
    # pattern = '[1-9]\d{4,9}@qq.com$'
    #正确的地址
    v = re.match(pattern,'12345@qq.com')
    #未限制结尾的前提下使用不正确的地址
    # v = re.match(pattern,'12345@qq.comabc')
    print(v)
    
    • \b 匹配单词边界
    import re
    pattern = r'.*\ber'
    # er左边界的情况
    s = '123,eroa'
    v = re.match(pattern, s)
    print(v)
    
    s1 = '123,oaer'
    pattern = r'.*er\b'
    # er为右边界的情况
    v1 = re.match(pattern, s1)
    print(v1)
    

在这里插入图片描述

  • \B 匹配非单词边界
import re
#ab不为左边界
pattern = r'.*\Bab'
v = re.match(pattern,'123 abr')
print(v)
#ab不为右边界
pattern = r'.*ab\B'
v = re.match(pattern,'wab')
print(v)

7. 匹配分组

  1. 分组就是用一对圆括号“()”括起来的正则表达式,匹配出的内容就表示一个分组。从正则表达式的左边开始看,看到的第一个左括号“(”表示第一个分组,第二个表示第二个分组,依次类推,需要注意的是,有一个隐含的全局分组(就是0),就是整个正则表达式。
    分完组以后,要想获得某个分组的内容,直接使用group(num)和groups()函数去直接提取就行。

  2. 语法:

字符功能
匹配左右任意一个表达式
(ab)将括号中的字符作为一个分组
\num引用分组num匹配到的字符串
(?p< name >)分别起组名
(?p=name)引用别名为name分组匹配到的字符串
  • 例子:
import re
pattern = r'[1-9]?\d$|100$'
s = '0'
s = '10'
# s = '9000'
s = '100'
# s = '1000'
v = re.match(pattern,s)
print(v)

			### 1. 匹配座机号码  区号 - 电话号 {5,8}  ()
pattern = r'(\d{3,4})-([1-9]\d{4,7})$'
# pattern = r'\d{3,4}-[1-9]\d{4,7}$'
s = '010-56668888'
v = re.match(pattern,s)
print('v: ', v)
print('v.group(): ', v.group())
print('v.group(1): ', v.group(1))
print('v.group(2): ', v.group(2))
print('v.groups(): ', v.groups())
print('v.groups()[0]: ', v.groups()[0])
print('v.groups()[1]: ', v.groups()[1])

在这里插入图片描述

			### 2. 匹配出网页标签内的数据  <html><title></title></html>
# pattern = r'<.+><.+>.+</.+></.+>'
pattern = r'<(.+)><(.+)>.+</\2></\1>' # 使用了:(ab) & \num
s = "<html><h1>我是标题</header></body>" # 注意前后标签不一致!
v = re.match(pattern,s)
print('v: ', v)

在这里插入图片描述

			### 3. 匹配分组别名以及引用别名
s = '<html><h1>我是一号字体</h1></html>'
# pattern = r'<(.+)><(.+)>.+</\2></\1>'
# 使用了:(?p<name>) 和 (?p=name)
pattern = r'<(?P<key1>.+)><(?P<key2>.+)>.+</(?P=key2)></(?P=key1)>'
v = re.match(pattern,s)
print('v: ', v)

在这里插入图片描述

8. re模块的高级用法

  1. re.search()
  • 作用:扫描字符串,查找正则表达式模式产生匹配的第一个位置,并返回相应的匹配对象,如果字符串中没有与模式匹配的位置,则返回None。
  • 用法:
import re
s = 'C语言阅读9999次'
v = re.match('\d+', s)
print(v)
s1 = 'python阅读6666次'
v1 = re.search('\d+', s1)
print(v1)
  1. re.findall()
  • 作用:从左到右扫描字符串,并按照找到的顺序返回匹配。如果模式中有一个或多个组,返回组列表。并且finall默认把分组的内容返回回去。
  • 用法:
import re
s = '阅读次数c:129 Python:999 C++:99'
list1 = re.findall(r'\d', s)
print(list1)
  1. re.sub()
  • 作用:返回通过替换repl替换字符串最左边不重叠的模式出现而得到的字符串。如果没有找到模式,则返回字符串不变。

    re.sub(pattern, repl, string, count=0, flags=0)

    • 参数:

      • pattern : 正则中的模式字符串。

      • repl : 替换的字符串,也可为一个函数。

      • string : 要被查找替换的原始字符串。

      • count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。

      • flags : 编译时用的匹配模式,数字形式。

  • 用法1:

import re
s = 'C语言阅读次数为:999次,C++阅读次数为:1000次,python阅读次数为:6666次'
pattern = r'\d+'
s = re.sub(pattern, '100', s, count=1)
print(s) 
  • 方法2:可以基于一个函数来进行处理
import re
s = 'C语言阅读次数为:999次,C++阅读次数为:1000次,python阅读次数为:6666次'
pattern = r'\d+'
def replace(result):
    return str(int(result.group())+1)
    
str1 = re.sub(pattern, replace, s)
print(str1)
  1. re.split()
  • 作用:通过制定模式拆分字符串
  • 语法:re.split(pattern, string[, maxsplit=0, flags=0])
Pattern匹配正则表达式
string要匹配的字符串
maxsplit分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数
flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
  • 用法:按照指定的格式拆分字符串
import re
s = 'He say:Hello,Word'
pattern =r'\s|:|,'
list1 = re.split(pattern,s)
print(list1)

9. 贪婪模式和非贪婪模式

  1. 贪婪模式:Python中数量词默认是贪婪的,总是尝试匹配尽可能多的字符。
  2. 非贪婪模式:总是尝试匹配尽可能少的字符,可以使用 “*”,"?","+","{m,n}" 后面加上 “?”,使贪婪变成非贪婪。
  • 例如:在"+" 后面加上 “?”,就变成了 非贪婪模式
    在这里插入图片描述
    在这里插入图片描述
  • 例子1:
import re
s = 'This is my tel:133-1234-1234'
# 贪婪模式
pattern1 = r'(.+)(\d+)-(\d+)-(\d+)'
v1 = re.match(pattern1,s)
# 非贪婪模式
pattern2 = r'(.+?)(\d+)-(\d+)-(\d+)'
v2 = re.match(pattern2,s)

print('贪婪:', v1)
print('贪婪:', v1.group(1))
# 在贪婪模式下,(.+)会尽可能的多要,只给(\d+)留下最后的3!
print('贪婪:', v1.group(2))
print('贪婪:', v1.group(4))
print('--------------------------')
print('非贪婪:', v2)
print('非贪婪:', v2.group(1))
print('非贪婪:', v2.group(2))
print('非贪婪:', v2.group(4))

结果:
在这里插入图片描述

  • 例子2:
import re
#贪婪模式
v1= re.match(r'abc(\d+)','abc123')
print(v1.group(1))
#非贪婪模式
v2= re.match(r'abc(\d+?)','abc123')
print(v2.group(1))
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值