7.17正则表达式与re模块

一。正则表达式

  在用户登录注册,以及身份验证时,会发现,如果在手机号的窗口输入字母等不是手机号的格式的字符串时,会报错,这种筛选字符串的功能就是由正则表达式提供。

  正则表达式是几乎所有编程语言都会设计的领域。

  它在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']

#在匹配部分加上()之后所切出的结果是不同的,
#没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项,
#这个在某些需要保留匹配部分的使用过程是非常重要的。

 

posted on 2019-07-17 20:58  一只萌萌哒的提莫  阅读(149)  评论(0编辑  收藏  举报