一。正则表达式
在用户登录注册,以及身份验证时,会发现,如果在手机号的窗口输入字母等不是手机号的格式的字符串时,会报错,这种筛选字符串的功能就是由正则表达式提供。
正则表达式是几乎所有编程语言都会设计的领域。
它在python所运用的范围有:
1.爬虫
2.数据分析
在普通的应用中还可以判断字符串是否符合规则。如果需要做手机号的识别,不用正则表达式可以用以下办法:
while True: phone_number = input('please input your phone number : ') if len(phone_number) == 11 \ and phone_number.isdigit()\ and (phone_number.startswith('13') \ or phone_number.startswith('14') \ or phone_number.startswith('15') \ or phone_number.startswith('16') \ or phone_number.startswith('17') \ or phone_number.startswith('18')): print('是合法的手机号码') else: print('不是合法的手机号码')
而使用正则表达式则只需要几行代码就可以实现功能:
import re phone_number = input('please input your phone number : ') if re.match('^(13|14|15|16|17|18)[0-9]{9}$',phone_number): print('是合法的手机号码') else: print('不是合法的手机号码')
所以,学会正则表达式会非常方便
在正则的编写中,可以使用http://tool.chinaz.com/regex/网站.
1.当你需要匹配特定字符时,直接写该字符即可。
2.字符组:[字符组]
在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示字符分为很多类,比如数字、字母、标点等等。假如你现在要求一个位置"只能出现一个数字",那么这个位置上的字符只能是0、1、2...9这10个数之一。如
正则 | 说明 |
[0123456789]a-z | 匹配0-9的字符 |
[0-9] | 匹配0-9的字符 |
[a-z] | 匹配a-z的字母 |
[A-Z] | 匹配大写a-z的字母 |
[0-9a-fA-F] | 匹配0-9,a-z,A-Z的字母 |
上面的匹配都是针对单个字符所出现的情况进行匹配
元字符 |
匹配内容 |
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
\n | 匹配一个换行符 |
\t | 匹配一个制表符 |
\b | 匹配一个单词的结尾 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结尾 |
\W |
匹配非字母或数字或下划线 |
\D |
匹配非数字 |
\S |
匹配非空白符 |
a|b |
匹配字符a或字符b |
() |
匹配括号内的表达式,也表示一个组 |
[...] |
匹配字符组中的字符 |
[^...] |
匹配除了字符组中字符的所有字符 |
其中,“.”匹配的是除了换行符意外的所有字符。
“\w”,word的意思,匹配字母或数字,或下划线。
“\s”,space的意思,匹配任意的空白符,包括tab,识别成一个空白
“\d",digit数字,匹配任意的数字。
”\W“,匹配非字母或数字或下划线
“\D”,匹配非数字
“\S”,匹配非空白符
这些互补可以匹配任意字符。
”\n“,匹配一个换行符
“\t”,匹配一个tab
"\b",匹配一个单词的结尾,如ad\b,将匹配所有以ad结尾的单词。
”^“,匹配字符串的开始,类似于”startwith“
”$“,匹配字符串的结尾,类似与”endswith“
这两个匹配的是整个字符串的开头和结尾,当两者一起使用时,中间是什么就只能是什么,不能多其他字符
”a|b“,匹配字符a,或者字符b,是单独匹配,在匹配时,当第一个字符匹配完后就不会去匹配第二个字符,所以可以将长的字符写在前面
"[]",匹配[]中的所有字符,是单个匹配。
[^].,在括号中使用^可以匹配除了该字符以外的其他字符。
量词
量词 |
用法说明 |
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
在字符组后面加上量词就可以匹配多个字符。
在正则表达式中,匹配都是贪婪配,也就是越多越好。
量词和量词不能结合在一起,而且量词只能限制紧挨着它的正则表达式。
https://www.cnblogs.com/Dominic-Ji/articles/11109067.html#_label10
{n}n中是指定个数的量词。
在量词后面加上?符号可以将贪婪匹配规则改成惰性匹配规则。
分组
当多个正则符号需要重复多次的时候,或者一个整体需要其他操作时,加上()进行操作
转义符\
在正则表达式中,有很多有特殊意义的是元字符,比如\n和\s等,如果要在正则中匹配正常的"\n"而不是"换行符"就需要对"\"进行转义,变成'\\'。
在python中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的,在字符串中\也有特殊的含义,本身还需要转义。所以如果匹配一次"\n",字符串中要写成'\\n',那么正则里就要写成"\\\\n",这样就太麻烦了。这个时候我们就用到了r'\n'这个概念,此时的正则是r'\\n'就可以了
在正则中\n相当于换行符,\\n相当于\n,经过转义的,python中字符串需要对\进行转义,所以要匹配\n需要写成‘\\\\n’,或者r'\\n’
.*?
.*?这个的意义是匹配单个字符,通常与另外一个字符联用,如.*?x,匹配字符直到x的出现。
<.*>贪婪匹配,从后遍历>符号,找到后截取之间的字符
<.*?>非贪婪匹配,从前遍历>符号,找到后截取之间的字符。
二。re模块
在re模块中,有三个方法处理正则表达式:
1。findll
res=re.findall('[a-z]+','aabbc222cskadjl1231231') print(res) #输出结果>>>['aabbc', 'cskadjl']
这个函数的语法是findll(”正则表达式“,”待匹配的字符串“),最后是以列表+字符串的形式输出结果
注意,在字符串中,会以空格为分隔,匹配到空格时会重新换一个字符串存储。
2.search
res=re.search('66','66,33,66,77,44,66,99') print(res) print(res.group()) #输出结果>>><_sre.SRE_Match object; span=(0, 2), match='66'> #66
在search中,查找字符串后,返回的是一个对象,并不会直接返回值,当需要里面的值时调用.group()方法取值,而且,search只会对其取一次值。
当没有取值时,会返回一个none,这个时候在使用.group()方法时,会报错,所以,使用search时,通常使用以下方法:
res=re.search('66','66,33,66,77,44,66,99') print(res) if res: print(res.group())
3.match
res=re.match('6','66 33 66 77 44 66 99') print(res) if res: print(res.group()) #输出结果>>><_sre.SRE_Match object; span=(0, 1), match='6'> #6
与search相同,match也是返回的对象,当需要其中的值时使用group方法对其取值,如果找不到i返回none但与search不同的是,match匹配的是字符串的开头部分,如果不是,直接返回none。
其他方法
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) # <callable_iterator object at 0x10195f940> print(next(ret).group()) #查看第一个结果 print(next(ret).group()) #查看第二个结果 print([i.group() for i in ret]) #查看剩余的左右结果
注意点:
1 findall的优先级查询:
import re ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com') print(ret) # ['oldboy'] 这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可 ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com') print(ret) # ['www.oldboy.com']
2.split的优先级查询
ret=re.split("\d+","eva3egon4yuan") print(ret) #结果 : ['eva', 'egon', 'yuan'] ret=re.split("(\d+)","eva3egon4yuan") print(ret) #结果 : ['eva', '3', 'egon', '4', 'yuan'] #在匹配部分加上()之后所切出的结果是不同的, #没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项, #这个在某些需要保留匹配部分的使用过程是非常重要的。