正则表达式与re模块

文章目录

  • 一、正则表达式
    • 1.应用场景
    • 2.正则表达式之字符组
    • 3.正则表达式之元字符
    • 4.正则表达式之量词
    • 5.贪婪匹配与非贪婪匹配
      • 1.贪婪匹配
    • 6.取消转义
  • 二、re模块的使用
  • 三、分组
    • 1.无名分组
    • 2.有名分组
    • 3.案例

一、正则表达式

正则表达式是一种用于匹配字符串的表达式,它描述了字符串的数量和顺序,可以用于搜索、替换和验证文本数据。使用正则表达式可以方便地在大量文本中查找、匹配和提取特定的模式,它在计算机编程语言和文本编辑器中广泛应用。

1.是一个对象,叫正则对象
2.是一个强大的字符串匹配和处理工具(除了处理字符串,其他的什么都做不了)
3.它是火星文,一般人很难理解(程序界的摩斯码)
4.它还是一种思维方式
5.容易学,但是也非常容易忘记

1.应用场景

某东手机号注册效验
要求:手机号必须是11位、手机号必须以13 15 17 18 19开头、必须是纯数字

1.普通代码实现

while True:
    # 1.获取用户输入的手机号
    phone_num = input('请输入您的手机号>>>>:').strip()
    # 2.判断是不是11位
    if phone_num == 11:
        #.3.判断是不是纯数字
        if phone_num.isdigit():
            # 4.判断手机号的开头
            if phone_num.startswith('13')or phone_num.startswith('15')or phone_num.startswith('17') or phone_num.startswith('18') or phone_num.startswith('18')
                print('手机号码输入正确')
            else:
            print('手机号开头不符合')
        else:
            print('号码不是纯数字')
    
    else:
        print('手机号必须是11位')

2.正则表达式实现

import re
phone_num = input('请输入您的手机号>>>>:').strip()
if re.match('^(13|14|15|18)[0-9]{9}$', phone_num):
    print('是合法的手机号码')
else:
    print('不是合法的手机号码')

2.正则表达式之字符组

字符组默认匹配方式是挨个挨个匹配
[0123456789]       匹配09任意一个数(全写)
[0-9]              匹配09任意一个数(缩写)
[a-z]	           匹配26个小写英文字母
[A-Z]		   匹配26个大写英文字母
[0-9a-zA-Z]	   匹配数字或者小写字母或者大写字母,用来验证十六进制字符

ps:字符组内所有的数据默认都是或的关系


eg:[0-9]为例,我们尝试用几个待匹配字符串得到匹配结果

待匹配字符串	匹配结果	          解释
'5'	         ['5']	           [0-9]中有5,所以可以匹配到5
'o'	         ['None']	   字母不符合条件
'79i1'	     ['7','9','1']	   每个匹配到的结果 ,都会从字符串中切出
'11111'	   ['1','1','1','1','1']   有几个1取几个1

3.正则表达式之元字符

元字符 匹配内容
. 匹配除换行符以外的所有字符
\w 匹配字母或数字或下划线
\s 匹配任意的空白符
\d 匹配数字
\t 匹配一个制表符
\b 匹配一个单词结尾
^ 匹配一个字符串的开始
s 匹配一个字符结尾开始
\W 匹配非字母或数字或下划线
\D 匹配非数字
\S 匹配非空白符
aIb 匹配字母a或者字母b
() 匹配括号内的表达式,也表示一个组
[…] 匹配字符组中的字符
[^…] 匹配除了字符组中的所有字符

4.正则表达式之量词

量词 用法说明
* 重复零次或更多次
+ 重复一次或更多次
重复一次或零次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次

5.贪婪匹配与非贪婪匹配

1.贪婪匹配

正则表达式默认为贪婪匹配,也就是尽可能多的向后匹配字符,比如 {n,m} 表示匹配前面的内容出现 n 到 m 次(n 小于 m),在贪婪模式下,首先以匹配 m 次为目标,而在非贪婪模式是尽可能少的向后匹配内容,也就是说匹配 n 次即可。

1.贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配

2.加上? 会将贪婪匹配模式转为非贪婪匹配模式,会匹配尽量短的字符串

贪婪模式转换为非贪婪模式的方法很简单,在元字符后添加“?”即可实现,如下所示:

量词 用法说明
.* .*?
+ +?
? ??
{n,m} {n,m}?

6.取消转义

在python中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的,在字符串中\也有特殊的含义,本身还需要转义。所以如果匹配一次"\n",字符串中要写成’\n’,那么正则里就要写成"\\n",这样就太麻烦了。这个时候我们就用到了r’\n’这个概念,此时的正则是r’\n’就可以了。

正则 待匹配字符 匹配结果 说明
\n \n False 因为在正则表达式中\是有特殊意义的字符,所以要匹配\n本身,用表达式\n无法匹配
\n \n True 转义\之后变成\,即可匹配
‘\\n’ ‘\n’ True 如果在python中,字符串中的’‘也需要转义,所以每一个字符串’'又需要转义一次
r’\n’ r’\n’ True 在字符串之前加r,让整个字符串不转义

二、re模块的使用

在Python中如果要使用正则,则需要使用到re(regluar express)模块

import re

ret = re.findall('a', 'eva egon yuan')  # 返回所有满足匹配条件的结果,放在列表里
print(ret) #结果 : ['a', 'a']

ret = re.search('a', 'eva egon yuan').group()
print(ret) #结果 : 'a'
# 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
# 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。

ret = re.match('a', 'abc').group()  # 同search,不过尽在字符串开始处进行匹配
print(ret)
#结果 : 'a'

ret = re.split('[ab]', 'abcd')  # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
print(ret)  # ['', '', 'cd']

ret = re.sub('\d', 'H', 'eva3egon4yuan4', 1)#将数字替换成'H',参数1表示只替换1个
print(ret) #evaHegon4yuan4

ret = re.subn('\d', 'H', 'eva3egon4yuan4')#将数字替换成'H',返回元组(替换的结果,替换了多少次)
print(ret)

obj = re.compile('\d{3}')  #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串
print(ret.group())  #结果 : 123

import re
ret = re.finditer('\d', 'ds3sy4784a')   #finditer返回一个存放匹配结果的迭代器
print(ret)  # 
print(next(ret).group())  #查看第一个结果
print(next(ret).group())  #查看第二个结果
print([i.group() for i in ret])  #查看剩余的左右结果

三、分组

1.无名分组

使用小括号括起来的正则表达式就是无名分组

 res = re.search('^[1-9](\d{14})(\d{2}[0-9x])?$','110105199812067023')
    print(res)
    print(res.group())  # 110105199812067023
    print(res.group(1))  # 10105199812067
    print(res.group(2))  # 023
    
    # findall针对分组优先展示   无名分组
    """
    如果是findall,分组优先展示,无名分组
    """
    res = re.findall("^[1-9](\d{14})\d{2}[0-9x]?$",'110105199812067023')
    print(res)  # ['023']

2.有名分组

使用小括号括起来的正则表达式然后起个名字就是有名的

res = re.search('www.(?Pbaidu|oldboy)(?P.com)','www.oldboy.com')
print(res.group())  # www.oldboy.com
print(res.group('name'))  # oldboy
print(res.group(0))  # www.oldboy.com
print(res.group(1))  # oldboy
print(res.group(2))  # .com
print(res.group('haha'))  # .com

3.案例

爬取红牛分公司官网数据

with open('a.txt', 'r', encoding='utf-8') as f:
    data = f.read()

import re
title_list = re.findall('

(.*?)

'
, data) address_list = re.findall("

(.*?)

"
, data) email_list = re.findall("

(.*?)

"
, data) phone_list = re.findall("

(.*?)

"
, data) res_list = zip(title_list, address_list, email_list, phone_list) # print(list(res_list)) for i in list(res_list): print(""" 公司名称:%s, 公司地址:%s, 公司邮编:%s, 公司电话:%s, """ % (i[0], i[1], i[2], i[3]))

你可能感兴趣的:(正则表达式,mysql,python)