python判断是否包含数字的成语_Python知识点记录三(正则表达式)

正则表达式

正则表达式是一个特殊的字符序列,可以检测一个字符串是否与我们设定的字符序列相匹配。

一、findall()方法

re模块下的findall()方法可以查找对应字符/字符串

最简单的方法可以查找字符串中的特定字符串:

importre

a= 'C|C++|Java|C#|Python|Javascript'r= re.findall('Python', a) #返回一个包含结果的列表

print(r)iflen(r):print('字符串中包含Python。')else:print('字符串中不包含Python。')

二、元字符和普通字符

对于上例findall()方法中的第一个实参'Python'即为普通字符,即表示字符本意的字符。

元字符:包括\d匹配0-9中的数字;\D匹配一个非数字字符,即[^0-9];等等。

importre

a= 'C0C++7Java8C#9Python6Javascrip'

#通过'\d'匹配数字字符

r = re.findall('\d',a)print(r)#通过'\D'匹配数字字符

r = re.findall('\D',a)print(r)

三、字符集

正则表达式中通过字符集设定字符的可能值,字符集通过[]表示。

如[0-9]表示0到9中的一个数字,即等同于元字符\d;[cf]字符集匹配c或者f;a[hc]b匹配一个三个字符的字符串,第一个字符为a,第二个字符为h或c,第三个字符为b;[^1]匹配所有不是1的字符。

importre

s0= 'He1ll2o,Wor3ld.'s1= 'abc, acc1, adc, aec, a1efc, ahc'

#匹配为e或o的字符

r0 = re.findall('[eo]', s0)#匹配0-3之间的字符

r00 = re.findall('[0-3]', s0)#匹配非小写字母的字符,且第二个字符为逗号

r01 = re.findall('[^a-z],',s1)#匹配第一个字符为a,第三个字符为c,第二个字符为c或f的字符串

r1 = re.findall('a[cf]c', s1)print(r0)print(r00)print(r01)print(r1)

四、概括字符集

上述提及的\d等元字符可以理解为概况字符集,即概况描述某一类字符的集合,如\d也可以表示为[0-9]字符集。

元字符\D可以用字符集[^0-9]表示;

元字符\w表示匹配单词字符(字母,数字,下划线)可以用字符集[A-Za-z0-9_]表示;

元字符\W表示匹配非单词字符,即%¥#@此类,也包括空格,制表符,回车,换行等空白字符;

元字符\s表示匹配空白字符,即空格、回车、换行符等。

importre

a= '_&python# 2java8\n9@php'

#\d匹配一个数字字符

r = re.findall('\d', a)#\D匹配一个非数字字符

r1 = re.findall('\D', a)#\w匹配一个单词字符(数字或字母字符或下划线)

r2 = re.findall('\w', a)#\W匹配一个非单词字符

r3 = re.findall('\W', a)#\s匹配一个空白字符

r4 = re.findall('\s', a)print(r)print(r1)print(r2)print(r3)print(r4)

五、数量词

对于以下代码:

importre

a= 'python 1111java678php'r= re.findall('[a-zA-Z]', a)print(r)#输出:['p', 'y', 't', 'h', 'o', 'n', 'j', 'a', 'v', 'a', 'p', 'h', 'p']

因为参数正则表达式为一个字符集,仅匹配单个字符;如果需要以单词的形式作为输出的元素,则需要用到数量词这个方式。

importre

a= 'python 1111java678php'r= re.findall('[a-z]{3,6}', a)print(r)#输出:['python', 'java', 'php']

参数中的[a-z]表示字符的匹配条件,{3,6}表示需要匹配的数量为3-6个,需要注意这里Python会默认采用贪婪的匹配方法,即如果已经匹配到3个字符后还会继续匹配,直到不再满足匹配条件,或达到匹配数量的最大值为止。

importre

a= 'python 1111java678php'r= re.findall('[a-z]{3,6}', a)print(r)#输出:['python', 'java', 'php']

Python默认为贪婪匹配,如果要采用非贪婪模式匹配,则需要在数量词后加个'?':

importre

a= 'python 1111java678php'

#非贪婪匹配方式

r = re.findall('[a-z]{3,6}?', a)print(r)#输出:['pyt', 'hon', 'jav', 'php']

*除了上述的'{}'表示数量词之外,也可以通过‘*’表示匹配星号前面字符0次或1次或无限次,通过'+'表示匹配加号前面字符至少1次,通过'?'表示匹配问号前面字符0次或1次。。

importre

a= 'pytho0python1pythonn2'

#匹配*前面的n0次或1次或无限次

r = re.findall('python*', a)#匹配+前面的n至少一次

r1 = re.findall('python+', a)#匹配?前面的n0次或1次

r2 = re.findall('python?', a)print(r)print(r1)print(r2)#输出:

'''['pytho', 'python', 'pythonn']

['python', 'pythonn']

['pytho', 'python', 'python']'''

需要注意这里问号和前述数量词{}之后问号的区别。

通过数量词实现上例,注意对比:

importre

a= 'pytho0python1pythonn2'

#通过数量词{}取n1-2次,贪婪模式

r = re.findall('python{1,2}', a)#通过数量词{}取n1-2次,非贪婪模式

r1 = re.findall('python{1,2}?', a)print(r)print(r1)#输出:

'''['python', 'pythonn']

['python', 'python']'''

六、边界匹配

如果有一个数字字符串,需要判断是否为一个QQ号码,比如qq='10000001'。

QQ号码的判断规则(假设)为4-8位的数字,如果单纯通过数量词查找:r = re.findall('\d{4,8}', qq),对于本例也是可以查找匹配出的,但如果

qq = '1234567890',通过前面的正则表达式'\d{4,8}'也可以匹配到数字字符串,但显然这个QQ号码超出了8位,这里就需要通过边界匹配符来界定匹配范围:

importre

qq= '1234567890'

#QQ号为4-8位,检测是否为QQ号码#通过边界匹配符'^...$'匹配整个字符串#第一个^表示从整个字符串开头匹配4-8个数字#最后一个$表示从整个字符串最末尾往前匹配4-8个数字#两者都匹配到的才为最终匹配到的结果

r = re.findall('^\d{4,8}$', qq)print(r)

再单独理解一下边界匹配符的第一个^和最后一个$的作用:

importre

qq= '123a4567890abchf'

#通过'^'匹配整个字符串开头的3-4个数字

r0 = re.findall('^\d{3,4}', qq)#通过'$'匹配整个字符串末尾的3-4个字母

r1 = re.findall('[a-zA-Z]{3,4}$', qq)print(r0)print(r1)'''输出:

['123']

['bchf']'''

七、组

前面数量词的使用中数量词针对的是其前面的单个字符,也可以通过组的概念将整组字符适用到数量词上:

importre

a= 'PythonPythonPythonPythonJSJSPython'

#找出是否含有连续三个Python,如果有则返回的是单个组,否则返回空列表

r = re.findall('(Python){3}', a)#找出是否含有连续三个PYthon且连着两个JS

r0 = re.findall('(Python){3}(JS){2}', a)#找出是否含有连续三个PYthon且连着三个JS

r1 = re.findall('(Python){3}(JS){3}', a)print(r)print(r0)print(r1)'''输出:

['Python']

[('Python', 'JS')]

[]'''

八、匹配模式参数

findall()还有第三个参数flags即指匹配模式,当参数值设为re.I则忽略正则表达式中的字母大小写;当参数值设为re.S则忽略

importre

language= 'PythonC#\nJavaPHP'

#忽略大小写的模式

r = re.findall('c#', language, re.I)#‘.’本来表示除了换行之外的所有字符,re.S模式表示'.'可以匹配任意字符#匹配整个字符串的最后两个字符

r0 = re.findall('.{2}$', language, re.S)#匹配c#或C#及后面1-3个字符(非贪婪)

r1 = re.findall('c#.{1,3}?', language, re.I |re.S)#匹配c#或C#及后面1-3个字符(贪婪)

r1 = re.findall('c#.{1,3}', language, re.I |re.S)print(r)print(r0)print(r1)'''输出:

['C#']

['HP']

['C#\nJa']'''

九、sub()/match()/search()函数

1、sub()函数可以实现查找后替换的功能。参数格式依此为正则表达式、需要匹配后替换的字符串(或函数)、原始字符串、匹配次数、模式参数。

importre

language= 'PythonC#JavaC#PHPC#'r= re.sub('C#', 'Javascript', language)print(r)#输出:PythonJavascriptJavaJavascriptPHPJavascript

第四个参数表示匹配后替换的次数,默认为0,表示不限制次数的替换,如果设置为非0的某个数值,则表示替换的最大次数。

importre

language= 'PythonC#JavaC#PHPC#'

#无限次替换

r1 = re.sub('C#', 'Javascript', language, 0)#最多1次替换

r2 = re.sub('C#', 'Javascript', language, 1)#最多2次替换

r3 = re.sub('C#', 'Javascript', language, 2)#对比字符串内置函数replace()

language0 = language.replace('C#', 'Javascript')print(r1)print(r2)print(r3)print(language0)'''输出:

PythonJavascriptJavaJavascriptPHPJavascript

PythonJavascriptJavaC#PHPC#

PythonJavascriptJavaJavascriptPHPC#

PythonJavascriptJavaJavascriptPHPJavascript'''

第二个参数除了直接指定为字符串,也可以指定为某个函数,其功能是把正则匹配出的字符串作为该函数参数,返回的字符串作为替换的字符串。

这里需要注意正则参数传递的时候实际是一个正则对象,需要通过访问其group()获得真正匹配到的字符串。

importredefconvert(value):

v=value.group()return v+'!'language= 'PythonC#JavaC#PHPC#'r= re.sub('C#', convert, language)print(r)#输出:PythonC#!JavaC#!PHPC#!

对于上例的convert()函数中,通过value.group()获取了匹配到的实际的字符串,这里value即是一个正则对象,除了group()函数,它还有span()方法,可以获取匹配到的字符串在原始字符串中的索引:

importredefconvert(value):#打印匹配到的字符在原始字符串中的索引

print(value.span())

v=value.group()return v + '!'language= 'PythonC#JavaC#PHPC#'r= re.sub('C#', convert, language)print(r)'''输出:

(6, 8) #匹配到的第一个C#对应索引为6,7

(12, 14)#匹配到的第一个C#对应索引为12,13

(17, 19)#匹配到的第一个C#对应索引为17,18

PythonC#!JavaC#!PHPC#!'''

importre

s= 'A8C3721D86'

#大于等于6的数字替换成9,其余数字替换为0

defconvert(value):

n=int(value.group())if n >= 6:return '9'

else:return '0'r= re.sub('\d', convert, s)print(r)#输出:A9C0900D99

importre

s= 'A8C372R1X16D86F333P50F7N'

#剔除所有的单个数字字符#两位数字大于50的替换为100,其余替换为0

defconvert(value):

n=int(value.group())if n < 10:return ''

elif n < 50:return '0'

else:return '100'r= re.sub('\d{1,10}', convert, s)print(r)#输出:AC100RX0D100F100P100FN

2、search()/match()函数

(1)match()尝试从字符串开头去匹配,匹配成功则返回第一个匹配的字符串,返回一个Match对象;如果没有匹配到则返回None。

(2)search()将搜索整个字符串,直到找到第一个匹配的字符串,返回一个Match对象;如果没有匹配到则返回None。

importre

s= 'A8C3721D86'r= re.match('\d', s)print(r)

r0= re.search('\d', s)#通过对象的group()获取匹配到的字符串

print(r0.group())

需要特别注意的是:search()和match()函数只最多匹配一次,匹配到一次后不再继续查找匹配,而findall()函数会查找整个字符串范围。

3、分组

除了前述提到的数量重复的作用外,还可以通过分组括号指定需要匹配的字符:

importre

s= 'life is short,i use python,\n i love python'r= re.search('life(.*)python', s, re.S)#group()获取整个分组的匹配,即'life(.*)python'

print(r.group())#也可以加下标0获取上述字符串

print(r.group(0))#可以加下标1获取上述字符串中的小分组

print(r.group(1))#groups()获取大分组下的小分组字符串,即上述(.*)

print(r.groups())#通过findall()是最方便直观的:

r1 = re.findall('life(.*)python', s, re.S)print(r1)print()

importre

s= 'life is short,i use python, i love python'

#多个分组的情况

r = re.search('life(.*)python(.*)python', s, re.S)#group()获取整个分组的匹配,即'life(.*)python(.*)python'

print(r.group(0))#可以加下标1获取上述字符串中的第一个小分组

print(r.group(1))#可以加下标2获取上述字符串中的第二个小分组

print(r.group(2))#通过groups()获取小分组

print(r.groups())#通过findall()是最方便直观的:

r1 = re.findall('life(.*)python(.*)python', s, re.S)print(r1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值