Python正则表达式及常用匹配
Posted Sicc1107
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python正则表达式及常用匹配相关的知识,希望对你有一定的参考价值。
1 正则表达式对象
re.RegexObject
re.compile() 返回 RegexObject 对象。
re.MatchObject
group() 返回被 RE 匹配的字符串。
- start() 返回匹配开始的位置
- end() 返回匹配结束的位置
- span() 返回一个元组包含匹配 (开始,结束) 的位置
2 正则表达式修饰符 - 可选标志
re.I 大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响 ^ 和 $
re.S 使 . 匹配包括换行在内的所有字符
re.U 根据Unicode字符集解析字符。这个标志影响 \\w, \\W, \\b, \\B.
re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。
3 正则表达式字符意义
符号 | 含义 |
---|---|
^ | 以什么开头 |
$ | 以什么结尾 |
. | 匹配任意字符,除了换行符 |
[…] | 用来表示一组字符,单独列出:[amk] 匹配 ‘a’,‘m’或’k’ |
[^…] | 取反 |
* | 匹配0个或多个 |
+ | 匹配1个或多个 |
? | 匹配0个或1个由前面的正则表达式定义的片段 |
{n} | { n} |
{n,} | 精确匹配 n+ 个 |
{n,m} | 精确匹配 n 到m个 |
a|b | a或b |
() | 标记 组合 |
\\w | 匹配字母数字及下划线,等价于 ‘[A-Za-z0-9_]’ |
\\W | 匹配非字母数字及下划线,等价于’[^A-Za-z0-9_] |
\\s | 匹配任意空白字符,等价于 [ \\f\\n\\r\\t\\v]。 |
\\S | 匹配任意非空字符 [^ \\f\\n\\r\\t\\v] |
\\d | 匹配任意数字,等价于 [0-9]. |
\\D | 匹配任意非数字,等价于 [^0-9]。 |
\\A | 匹配字符串开始 |
\\Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。 |
\\z | 匹配字符串结束 |
\\G | 匹配最后匹配完成的位置。 |
\\b | 单词边界 |
\\B | 非单词边界 |
组合使用
[ab]cde | 匹配 acde 或 bcde |
---|---|
abc[de] | 匹配 abcd 或 abce |
[abcdef] | 匹配中括号内的任意一个字母 |
[0-9] | 匹配任何数字。类似于 [0123456789] |
[a-z] | 匹配任何小写字母 |
[A-Z] | 匹配任何大写字母 |
[a-zA-Z0-9] | 匹配任何字母及数字 |
[^0-9] | 取反 匹配数字之外 |
.* | 任意一个字符 出现0次或多次 尽可能多的匹配 |
.*? | 只匹配符合条件的最少字符 尽可能少的匹配 |
re.match函数
re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。
re.match(pattern, string, flags=0)
pattern 匹配的正则表达式 string 要匹配的字符串。 flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
import re
#在起始位置匹配 匹配 www 是不是在开头
print(re.match('www', 'www.aaa.com')) # <re.Match object; span=(0, 3), match='www'>
print(re.match('www', 'www.aaa.com').span()) # (0, 3)
print(re.match('com', 'www.bbb.com')) # None
line = "wo shi ni baba oo aa"
#最后的 .*就是后面所有的 re.M 多行匹配,影响 ^ 和 $ re.I 大小写不敏感
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)
if matchObj:
print("matchObj.group() : ", matchObj.group()) #返回匹配到的整个表达式的字符串
print("matchObj.group(1) : ", matchObj.group(1)) #返回标记的1个() (.*)就是任意字符出现0个或多个 在这就是 wo
print("matchObj.group(2) : ", matchObj.group(2)) #返回标记的2个() (.*?) 只匹配符合条件的最少字符 和.*是差不多的 就是 ni
else:
print("No match!!")
#matchObj.group() : wo shi ni baba oo aa
#matchObj.group(1) : wo
#matchObj.group(2) : ni
re.search方法
re.search 扫描整个字符串并返回第一个成功的匹配。
re.search(pattern, string, flags=0)
print(re.search('ab', 'www.abcdef.com').span()) # (4, 6)
print(re.search('cc', 'www.abcdef.ccom').span()) # (11, 13)
替换re.sub
re.sub用于替换字符串中的匹配项。
re.sub(pattern, repl, string, count=0, flags=0)
pattern : 正则中的模式字符串。rep : 替换内容,也可为一个函数。 string : 要被查找替换的原始字符串。count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
num1 = "a11a-b22b-c33c-d44d-e55e #sdsdasdas111da"
# re.sub(pattern, repl, string, count=0, flags=0)
##删除#号之后的 将#号之后的所有 替换为空
num2 = re.sub(r'#.*$', "", num1)
print(num2) #a11a-b22b-c33c-d44d-e55e
# #\\D 匹配任意非数字 替换为空
num3 = re.sub(r'\\D', "", num1)
print(num3) #1122334455111
def test(x):
print(x)
y = int(x.group())
y *= 2
return str(y)
# 内部调用test方法时 会把 匹配到的 数据以 re.Match的格式传递
print(re.sub(r'\\d+', test, p))
re.compile 函数
函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。
re.compile(pattern,[flags])
pattern : 一个字符串形式的正则表达式 flags : 可选,表示匹配模式,比如忽略大小写,多行模式等
pattern = re.compile(r'([a-z]+) ([a-z]+) (.*)', re.I)
str1 = pattern.match('Wo shi ni Ba ba')
print(str1) #<re.Match object; span=(0, 15), match='Wo shi ni Ba ba'>
print(str1.group(0)) #Wo shi ni Ba ba
print(str1.group(1)) #Wo
print(str1.group(2)) #shi
print(str1.group(3)) #ni Ba ba
print(str1.groups()) #('Wo', 'shi', 'ni Ba ba')
print(str1.span(1)) #(0, 2)
print(str1.span(2)) #(3, 6)
print(str1.span(3)) #(7, 15)
findall
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
findall(string, [pos], [endpos])
string : 待匹配的字符串。 pos : 可选参数,指定字符串的起始位置,默认为 0。 endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。
pattern = re.compile(r'\\d+') # 查找数字
result1 = pattern.findall('aaa 123 bbb 456 ccc 789 ddd 222')
result2 = pattern.findall('aa11bbb22cc33dd44cc55', 0, 10) # 0 10限制查找的下标
print(result1) #['123', '456', '789', '222']
print(result2) #['11', '22']
re.finditer
和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。
re.finditer(pattern, string, flags=0)
pattern 匹配的正则表达式 string 要匹配的字符串。flags 标志位
it = re.finditer(r"\\d+","aaa 123 bbb 456 ccc 789 ddd 222")
for match in it:
print(match.group())
#123
#456
#789
#222
re.split
split 方法按照能够匹配的子串将字符串分割后返回列表
re.split(pattern, string, maxsplit=0, flags=0) maxsplit分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。
m = re.split('\\W+', 'aaa 123 bbb 456 ccc 789 ddd 222') #匹配非字母作为分割
print(m) #['aaa', '123', 'bbb', '456', 'ccc', '789', 'ddd', '222']
m = re.split(' ','aaa 123 BBB 456 ccc 789 ddd 222') #匹配非空格作为分割
print(m) #['aaa', '123', 'BBB', '456', 'ccc', '789', 'ddd', '222']
m = re.split('[0-9]{3}','aaa 123 BBB 456 ccc 789 ddd 222') #出现 3 个数字相连 为分割
print(m) #['aaa ', ' BBB ', ' ccc ', ' ddd ', '']
练习:
#判断用户输入是否是数字 fullmatch 全文匹配
import re
num = input('请输入一段数字:')
if re.fullmatch(r'\\d+(\\.?\\d+)?',num): #\\d+ 数字匹配一个或多个 \\.?转义. 出现0 或1 次 后面再是数字 再把小数点和小数点后面的 作为整体 0次或1次
print('是个数字')
print(num)
else:
print('不是一个数字')
m = 'aaa_123_bbb-456-CCC_789_ddd_222'
#r^\\D[a-z0-9A-Z_\\-]{3,13} #以非数字开头 数字字母下滑线组成的 长度4 到14 位的字符串
b = re.match(r'^\\D[a-z0-9A-Z_\\-]{3,13}', m)
print(b.group()) #aaa_123_bbb-45
print(b.span()) #(0, 14)
#匹配游戏
#r'^[0-9a-zA-Z_]{0,19}@[0-9a-zA-Z]{1,13}\\.[com,cn,net]{1,3}$'
#匹配手机号
#r'^1(3\\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8[0-9]|9[0-9])\\d{8}$'
#匹配身份证号 前6位的地区:[1-9]开头 \\d数字出现5个 (18|19|20)\\d{2} 出生的年份18几几 19几几 20几几 1800-2099 月份 ((0|[1-9])|(10|11|12)) 日期 (([0-2][1-9])|10|20|30|31) 最后是3个数字, 再加一位 数字或者Xx结尾
#r'^[1-9]\\d{5}(18|19|20)\\d{2}((0|[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$'
以上是关于Python正则表达式及常用匹配的主要内容,如果未能解决你的问题,请参考以下文章
python 基础 8.0 regex 正则表达式--常用的正则表达式