【Python 学习】基础知识(3)——re库

一、正则表达式

1. 简介

正则表达式(regular expression)(regex)(RE),用来简洁表达一组字符的表达式,由字符和操作符构成。
正则表达式常用于文本处理,表达文本类型的特征,同时查找或替换一组字符串、匹配字符串的全部或部分

2. 正则表达式中的符号

按照符号的功能,可将其分为三类,一般情况下表达式都是由这三种符号组成的。

2.1 正则字符

正则符号描述实例
\转义字符。例如, ‘n’ 匹配字符 ‘n’。
( )标记一个子表达式的开始和结束位置。\( \)
.匹配除换行符 \n 之外的任何单字符。\.
||左右表达式任意一个abc|def表示abc或def
\d匹配字符串中的单个数字等价于[0-9]
\D匹配⾮数字,即不是数字
a-zA-Z匹配全部英文字符
0-9匹配全部数字
\w单词字符等价于等价于[A-Za-z0-9]
\W匹配非单词字符
\s匹配字符串中的\n,\t,空格
\S匹配非空白字符
[]中括号内任意正则符号均可参与匹配`[abc]表示a、b、c,[a-z]表示a到z的单个字符
[^]当在方括号表达式中使用,^对其后的正则表达式进行了反义表达。[^abc]表示非a或非b或非c的单个字符

2.2 限定字符

正则符号描述匹配自己时
*匹配前面的子表达式零次或多次。abc*表示ab、abc、abcc、abccc等
?匹配前面的子表达式零次或一次abc*表示ab、abc
+匹配前面的子表达式一次或多次。abc+表示abc、abcc、abccc等
{m}n 是一个非负整数。匹配确定的 m 次。ab{2}c表示abbc
{m,}m 是一个非负整数。至少匹配m 次。
{m, n}m 和 n 均为非负整数,其中m <= n。扩展前一个字符m至n次(含n)ab{1,2}c表示abc,abbc

2.3 定位字符

正则符号描述匹配自己时
^匹配输入字符串的开始位置。\^
$匹配输入字符串的结尾位置\$
\b匹配一个单词边界,即字与空格间的位置
\B非单词边界匹配

2.4 经典实例

正则符号描述
^[A-Za-z]+$由26个字母组成的字符串
^[A-Za-z0-9]+$由26个字母和数字组成的字符串
^-?\d+$整数形式的字符串
^ [1-9]*[0-9]*$正整数形式的字符串
[1-9]\d{5}中国境内邮政编码,6位
[\u4e00-\u9fa5]匹配中文字符
\d{3}-\d{8}|\d{4}-\d{7}国内电话号码 3位-8位或4位-7位

二、re库

1. 简介

2. 常用方法

re库常用函数作用
re.compile(r'\w{3}') re模块下的compile() 函数将正则表达式的字符串形式编译为一个 Pattern 对象
特别提示:正则表达式使用时,对特殊字符进行转义,所以如果我们要使用原始字符串,需在字符串前面加一个r 前缀。
re.search(pattern,string)在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象
re.match(pattern, string)从一个字符串的开始位置起匹配正则表达式,返回match对象
re.findall(pattern, string)根据pattern返回匹配结果(列表)
re.finditer(pattern, string)搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象
re.split(pattern, string)使用pattern分割string,返回列表
re.sub(pattern, repl, string)使用repl替换string中的pattern

2.1 re.search(pattern,string,flags=0)

pattern:匹配的正则表达式
string:要匹配的字符串
flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

flags 如:
re.I 忽略大小写
re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
re.M 多行模式
re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)
re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
re.X 为了增加可读性,忽略空格和 # 后面的注释

2.2 re.match(pattern,string,flags=0)

(1)与re.search()的区别在于:
re.match()是从起始位置就匹配成功,否则返回none;
re.search()匹配整个字符串,直到找到一个匹配成功的。注意:一次匹配,如果后面还有匹配的也不会查找了.
(2)提取数据:group

  • group()用来提取分组截获的字符串,()用来分组。
  • group() 同group(0)用来表示匹配正则表达式整体结果
  • group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分。
  • 当嵌套分组时(有两层括号),即r'((expression1)(expression2))'的情况时,最外层的分组被解释成一个整体group(1),里层的分组解释从group(2)开始
  • 没有匹配成功的,re.search()返回None。
(3)常用方法
group(): 用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group() 或 group(0)
span(): 返回匹配字符串的起始位置
start():用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;
end():用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0 

2.2 re.findall(string[, pos[, endpos]])

  • 其中,string 是待匹配的字符串,pos 和 endpos 是可选参数,指定字符串的起始和终点位置,默认值分别是 0 和 len (字符串长度)。
  • findall 以列表形式返回
import re
pattern=r'([a-z]+) ([a-z]+)'
text='hello World python'
#Example 1 search
search_list = re.search(pattern, text) 
if search_list:
    print(search_list)
print(search_list.group())
print(search_list.group(1))
print(search_list.group(2))
#结果
<re.Match object; span=(7, 18), match='orld python'>
orld python
orld
python

#Example 2 match
#2.1
match_list = re.match(pattern, text) 
if match_list:
	 print(match_list)
#结果为none 因为match是从头开始匹配

#2.2
#Example 2 match
pattern2=r'([a-z]+) (\w{5})'
text='hello World python'
match_list = re.match(pattern2, text) 
if match_list:
    print(match_list)
print(match_list.group(1))
print(match_list.group(2))
#结果
<re.Match object; span=(0, 11), match='hello World'>
hello
World

#Example 3 findall
findall_list = re.findall(pattern, text) 
if findall_list:
	 print(findall_list)
#结果
['hello', 'orld']

2.3 re.split(string[, maxsplit])

其中,maxsplit 用于指定最大分割次数,不指定将全部分割。跟字符串的分隔类似,但是这个更加灵活。

import re
pattern3=r'[\s\d]+'
text='hello World python'
split_list=re.split(pattern3,text) ## 表示遇到空白字符\s或者数字\d,都会切割。+表示如果有多个空格也可以切割。
print(split_list)
#结果
['hello', 'World', 'python']

#以上也可以写成
split_list=re.split(r'[\s\d]+','hello World python')

2.4 re.sub(repl, string[, count]) ==>re.sub(pattern, repl, string)

repl 可以是字符串也可以是一个函数:

  • 如果 repl 是字符串,则会使用 repl 去替换字符串每一个匹配的子串,并返回替换后的字符串,另外,repl 还可以使用 id 的形式来引用分组,但不能使用编号 0;
  • 如果 repl 是函数,这个方法应当只接受一个参数(Match 对象),并返回一个字符串用于替换(返回的字符串中不能再引用分组)。
  • count用来指定最多替换的次数,默认为全部替换。
#Example 1 将数字进行更改
pattern = '\d+'
repl = 'NUM'
string = """Python是一门面向对象的编程语言,诞生于1991年。\
一般情况下Python是Java的20%,所以说人生苦短,我用Python。"""
re.sub(pattern, repl, string)

#Example 2 对某一个词汇进行同一表达
text = 'Python是一门面向对象的编程语言,诞生于1991年。\
一般情况下Python语言是Java的20%。Python目前使用人数很多。'
pattern = '[(Python语言)+(Python)]+'   #要加+,否则变成[]内任一字符参与替换,从而导致多次替换
repl = 'Python语言'
re.sub(pattern, repl, text)

#Example 3 替换函数用法
def read_num(num):
    num_temp = num.group() 
    num = int(num_temp) + 1
    return str(num)
 
s = "阅读次数为:999,浏览次数为2000"
ret = re.sub(r"\d+",read_num,s)
print(ret)
#print结果:阅读次数为:1000,浏览次数为2001
#sub方法会将匹配到的数据依次传到方法read_num中,\
#所以我们首先要使用group方法获取到每个参数的具体内容,然后将这个字符串转为int类型,再加1,注意return的时候要转为字符串,这个位置的值只能是字符串

3. 贪婪与非贪婪

  • 贪婪匹配:Python默认贪婪匹配,即尽可能多的匹配。
  • 非贪婪匹配:在 “*” “?” “+” “{m,n}”的后面加上?就可以做到非贪婪,尽可能少的匹配
s=“this is a number: 0312-265-8888”
ret = re.match(r".+(\d+-\d+-\d+)",s)  #因为要匹配数字,所以把号码用括号括起来
ret.group()
#'this is a number:0512-587-4567' #这个结果是这种方式提取到的号码,明显不是我们想要的.
#贪婪方式:前面的.+尽可能的匹配多一些,后面的\d+只要有一个数字就可以满足(造成group(1)前一个只有一个2),所以别的数字都归到了.+里面
ret.group(1)    
#'2-587-4567'

#改成非贪婪模式
ret = re.match(r".+?(\d+-\d+-\d+)",s)
ret.group(1)  
#'0312-265-8888'  此时尽可能多的匹配后面的\d+。
  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值