欢迎第 位访客

Day 4-11 re正则表达式

正则表达式就是字符串的匹配规则,在多数编程语言里都有相应的支持,python里对应的模块是re

'.'     默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
'^'     匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$'     匹配字符结尾, 若指定flags MULTILINE ,re.search('foo.$','foo1\nfoo2\n',re.MULTILINE).group() 会匹配到foo1
'*'     匹配*号前的字符0次或多次, re.search('a*','aaaabac')  结果'aaaa'
'+'     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
'?'     匹配前一个字符1次或0次 ,re.search('b?','alex').group() 匹配b 0次
'{m}'   匹配前一个字符m次 ,re.search('b{3}','alexbbbs').group()  匹配到'bbb'
'{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
'|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
'(...)' 分组匹配, re.search("(abc){2}a(123|45)", "abcabca456c").group() 结果为'abcabca45'


'\A'    只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的,相当于re.match('abc',"alexabc") 或^
'\Z'    匹配字符结尾,同$ 
'\d'    匹配数字0-9
'\D'    匹配非数字
'\w'    匹配[A-Za-z0-9]
'\W'    匹配非[A-Za-z0-9]
's'     匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'

'(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'}
re的匹配语法有以下几种
  • re.match 从头开始匹配  
  • re.search 匹配包含
  • re.findall 把所有匹配到的字符放到以列表中的元素返回
  • re.split 以匹配到的字符当做列表分隔符
  • re.sub 匹配字符并替换
  • re.fullmatch 全部匹配

 

re.match 从头开始匹配

1 import re
2 #查找字符串中是数字
3 s = "abc3kd4"
4 print(re.match("[0-9]",s))  # 这里的从头开始匹配指的是第一个字符是数字,并不是说从第一个字符开始匹配
5 #输出:None

re.search 匹配包含

re.match与re.search的区别

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。

import re
#查找字符串中是数字
s = "abc3kd4"
print(re.search("[0-9]",s))  # 找到数字就返回.返回的是一个对象.如果拿到值呢?
search_re = re.search("[0-9]",s)
if search_re:
    print(search_re.group())        # 取值
# 输出:3

re.findall 把所有匹配到的字符放到以列表中的元素返回

import re
#查找字符串中是数字
s = "abc3kd4"

print(re.findall("[0-9]",s))  # 找到所有的数字,返回一个列表.

#输出:['3', '4']

 常用re匹配规则:

 1 #  . 匹配任意字符,除换行符\n以外
 2 
 3 s = "123ag1c1d1*A\n"
 4 print(re.search(".", s).group())  # 返回了第一个字符
 5 print(re.findall(".", s))           # 返回全部的字符串,但是并没有返回换行符\n
 6 # 如果我想匹配12这2个字符呢??
 7 print(re.search("..",s))        # 条件写2个"."就可以了.以此类推
 8 
 9 # ^  匹配字符的开头,只能匹配开头的字符,不能匹配中间的字符
10 print(re.search("^1", s).group())   # 返回一个1
11 print(re.search("^123", s).group())     #返回123
12 print(re.search("^2", s).group())      # 这样就什么也匹配不到,会报错.
13 
14 # $ 匹配字符结尾.
15 
16 print(re.search("A$", s).group())   # 匹配以A结尾 返回A
17 print(re.search("cd*A", s).group())  # 匹配
18 
19 # * 匹配*号前的//字符,0次或多次.匹配不到就是0次
20 
21 print(re.search("1*", s).group())   # 被匹配的字符必须相连才能返回多次. 返回1
22 s2= "1112345"
23 print(re.search("1*", s2).group())  # 匹配多个相连的1 返回111
24 # + 匹配+号前一个字符,一次或多次
25 
26 print(re.search("ab+", "bcdcabbbcd").group())  # 相当于匹配a开头后面和b结尾,直到不是b结尾为止.  返回abbb
27 
28 # ? 匹配?号一个字符0次或1次
29 
30 print(re.search("ab?", "acbcdefsfabc").group())  # 返回首次匹配到的字符,如果匹配到a或者b其中一个字符,就返回.返回a
31 
32 print(re.search("a{2}", "abcdada").group())    # 匹配2个相连的a,如果没有就报错
33 print(re.search("a{2}", "abcdaada").group())    # 匹配a2次.返回aa
34 
35 # {n,m}  匹配n到m次,比如{1,9}
36 
37 print(re.search("[a-z]{1,3}","dadrefijlwea"))  # 匹配a-z中字符1到3次.返回dad
38 print(re.search("[a-z]{1,3}","da1adrefijlwea"))  # 返回da
39 """在开头d后面加上一个1.看看返回什么? 返回了一个d.也就是说,只要匹配到满足1至3中任何一个值的字符,就返回,注意是从最大的数量开始匹配
40 比如,先匹配3个字符,没有的话,再匹配2个.以此类推"""
41 
42 # | 匹配"|"左边或者右边的字符.
43 
44 print(re.search("jack|Jack","jack").group())  # 匹配jack或者Jack
45 print(re.search("[j|J]ack","Jack").group())     # 效果同上,简写了.
46 
47 #(...)  分组匹配,把匹配到内容分开
48 print(re.search("[a-z]+[0-9]+", "jack2018").group())  # 这样我们得到的一个是jack2018的字符串,但是并未分开
49 print(re.search("([a-z]+)([0-9]+)", "jack2018").groups())  #  在2个条件上加上(),取值的方法变成了groups.返回'jack', '2018')
50 
51 
52 # (?P<name>...)   分组匹配.
53 id = "512501197203035172"
54 res = re.search("(?P<pro>\d{3})(?P<city>\d{3})(?P<bron_year>\d{4})",id)  #定义好格式,把身份证号分开,输出省份城市代码和出生年
55 print(res.groupdict())  # {'city': '501', 'bron_year': '1972', 'pro': '512'}

 

 1 print(re.split("\d+", "jack19nick23shanshan18")) # 按照数字分割字符
 2 
 3 print(re.findall("\d+", "jack19nick23shanshan18"))  # 找到所有的数字
 4 
 5 re.split()
 6 print(re.split("\d+|#|-", "abc12jack-nick#joseph50chen")) # 以数字或#号或-号分割字符.返回所有可以分割的字符串
 7 
 8 # 转义.需求如下:有一组字符以|符号作为分界,要取出|两边所有的字符. s = "jack|nick|joseph|lucy"
 9 s = "jack|nick|joseph|lucy"
10 # print(re.split("|", s))       # 如果我们这样写就出错了.因为|也是一个re的方法,这里就相当与使用了 |方法.但是|两边又没有写条件,所以报错.
11 print(re.split("\|", s))      # 在分隔符前加一个\即可,\表示转意.
12 
13 #有个特殊的分隔符\,转意的时候,要写多次
14 s = "c:\\1234\\123.txt"
15 print(re.split("\\\\" , s))     # 要写4个\才能完成转意.
16 
17 
18 s='9-2*5/3+7/3*99/4*2998+10*568/14'     # 去掉所有的特殊字符
19 # print(re.split("\W", s))                # 可以用\W表示特殊字符
20 print(re.split(r'[\+\-\*/]',s))
21 
22 s1 = "jack22nick18chen25lucy"
23 print(re.sub("\d+","_",s1))     #把所有的数字替换成一个_
24 
25 print( re.fullmatch("\w+@\w+\.(com|cn|net)","junkec@126.cn").group())
26 
27 
28 pattern = re.compile("\w+@\w+\.(com|cn|net)")  # 定义一个规则.这样下次直接调用就可以.不用每次都写规则,提高程序运行速度.
29 s = pattern.fullmatch("junike@126.com").group()
30 print(s)

 RE练习:

1.验证手机号码是否符合规范.

2.验证邮箱是否符合规范.

 1 """
 2 1.验证手机号是否合法
 3 
 4 2.验证邮箱是否合法
 5 """
 6 import re
 7 
 8 
 9 def auth_email(string):
10     email = (re.fullmatch("\w+@\w+\.(com|cn|net|com.cn|net.cn)",string))
11     if email == None:
12         print("邮箱地址不合法!")
13     else:
14         print(string + ",是一个合法的邮箱地址!")
15 
16 
17 
18 def auth_mobile(string):
19     res = re.fullmatch("^((13[0-9])|(15[0-3]|[5-9])|(18[0-9]))\d{8}", string)
20     if res == None:
21         print(string + ",不是一个合法的手机号码!")
22     else:
23         print(string + ",是一个合法的手机号码!")
24 
25 while True:
26     msg = """
27     1.验证邮箱
28     2.验证手机
29     """
30     print(msg)
31     choice = input("choice num>>>")
32     if choice == "1":
33         emal_address = input("email_address:")
34         auth_email(emal_address)
35     elif choice == "2":
36         mobile = input("mobile num:")
37         auth_mobile(mobile)
38     else:
39         print("input error.")
40         continue
View Code

 

posted @ 2018-04-10 22:46  大橡皮  阅读(304)  评论(0)    收藏  举报