re模块

正则表达式(动态模糊的匹配(如:匹配姓陈的,并且名字不超过两个字的))
功能:用来匹配字符串
思路:基本用法不复杂,重要的是**套路**
            使用不复杂,复杂的是匹配条件

#示例一
import re
#匹配chen
res = re.match("^Chen","chenmingzhi123")
print(res.group())

#示例二
#匹配chen和后面的数字
res1 = re.match("^Chen\d","Chen1234MingZhi123")
#  \d 匹配数字,只代表一个数字;此处只匹配Chen后面一个数字
print(res1.group())

#  \d+ 匹配数字,代表一个或多个数字
res2 = re.match("^Chen\d+","Chen1234MingZhi123")
print(res2.group())

常用正则表达式符号

"."     默认匹配除换行符(\n)之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行。
"^"     匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
"$"     匹配整个文本最后以什么结尾的,或e.earch("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以
"*"     匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac")  结果为
"+"     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba")  结果["ab","abb"]
"?"     匹配前一个字符1次或0次,而前面一个字符的前面所有字符是全匹配
"{m}"   匹配前一个字符m次
"{n,m}" 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果为['abb','ab','abb']
"|"     匹配 | 左边或者右边的字符,re.search("abc|ABC","ABC343abc")   结果为['ABC']
"(..){..}(..){..}..."   分组匹配,re.search("(abc){2}a(123|456)c","abcabca456c").group() 结果为:abcabca456c

"\A"    匹配从字符开头匹配,同"^"一样, re.search("\Aabc","alexabc") 是匹配不到的
"\Z"    匹配字符结尾,同"$"一样
"\d"    匹配数字0-9
"\D"    匹配非数字(匹配除了数字以外包括特殊字符、空格、换行符等)
"\w"    匹配[A-Za-z0-9]
"\W"    匹配非[A-Za-z0-9]
"\s"    匹配空白字符、\t、\n、\r

'(?P...)'   分组匹配

常用正则表达式符号练习

############ “.” 点匹配练习 ############
#匹配从开头的任意一个字符
print(re.match("^.","Chen1234MingZhi123"))
#匹配任意字符
print(re.match("^.+","Chen1234MingZhi123"))
print(re.match(".+","Chen1234MingZhi123"))

########### “$” 匹配练习,匹配文本末尾以什么结尾 ############
#$匹配以什么结尾
#匹配M开头
print(re.search("M.+","Chen1234MingZhi123i"))
#匹配M开头 i结尾的 Mingzhi,如果Mingzhi有多个,匹配到第一个就返回了;
print(re.search("M[a-z]+","Chen1234MingzhiMingzhi123i"))
#匹配M开头 中间有大写字母  i结尾的 MingAzhi
print(re.search("M[a-z]+[A-Z][a-z]+i","Chen1234MingAzhiMingzhi123i"))
#匹配M开头  文本末尾以 i 结尾的 MingAzhiMingzhi123i
print(re.search("M[a-zA-Z0-9]+i","Chen1234MingAzhiMingzhi123i"))
#匹配 #hello#
print(re.search("#.+","1234#hello#"))
print(re.search("#[a-z]+#","1234#hello#"))

############ “+” 匹配练习,匹配前一个字符1次或多次 ############
#匹配 以a开头 后边有一个b或者多个b结尾的
print(re.findall("ab+","ab+cd+abb+bba")  )

############ “*” 匹配练习,匹配*号前的字符0次或多次 ############
print(re.findall("ab*","cabb3abcbbac"))

############ “?” 匹配练习,匹配?号前一个字符出现过1次或0次 ############
#注意:匹配?前一个字符出现过一次或0次,而?号前一个字符前面的所有字符都是全匹配,然后再匹配?号前的字符
#匹配?字符前一个字符 出现过0次或一次
print(re.search("ab?","ababcd"))       #结果为ab
print(re.search("ab?","jljlabjlkjl")) #结果为ab
print(re.search("ab?","haaababd"))    #结果为a (先匹配a,再匹配b,而匹配到第一个a后面的字符仍然是a 不是b 所以返回a)
print(re.search("aaa?","bcabd"))      #结果为None (匹配第一个a 匹配第二个a 而第一个a后面是b 所以返回None)
print(re.search("aaab?","bcaaaabd")) #结果为aaa (首先匹配到三个a 匹配第四个b 但是前三个a后面还是a 所以返回aaa)
print(re.search("abc?","bcaaaabcd"))

############ 匹配范围 匹配练习 ############
print("======")
print(re.search("[0-9]{3}","aa1b25cc345def"))
#匹配数字0-9 出现过2 到 3 次
print(re.search("[0-9]{2,3}","aa1b25234324cc345def"))

############ findall匹配返回所有结果 ############
#匹配数字0-9  出现过1次到3次的所有结果 打印出来
print(re.findall("[0-9]{1,3}","122fdfd324343fdfd6565"))
#匹配所有的数字打印出来
print(re.findall("\d+","122fdfd324343fdfd6565"))

############匹配 | 左边或者右边的字符 ############
print(re.search("abc|ABC","ABC3434abc").group())
print(re.findall("abc|ABC","ABC3434abc"))

############分组匹配 ############
print(re.search("abc{2}","nameabcc"))
#匹配括号里的abc 匹配两次
print(re.search("(abc){2}","nameabcabc"))   #返回abcabc
#匹配abcabc||=
print(re.search("(abc){2}(\|){2}=","nameabcabc||="))
#匹配思路:1.匹配括号里abc 匹配两次;2.匹配括号里管道符 匹配两次;3.匹配一个等于号

#匹配abcabc||=||==
print(re.search("(abc){2}(\|\|=){2}=","nameabcabc||=||=="))

############ \A 匹配 ############
print(re.search("\A[0-9]+[a-z]","123abc"))  #结果为:123a
print(re.search("\A[0-9]+[a-z]\Z","123a"))  #结果为:123a

############ \D 匹配非数字之外的所有字符 ############
print(re.search("\D+","343fsdf@$#^%%^ #$#-="))  #结果为:fsdf@$#^%%^ #$#-=

############ \w 匹配大小写字母和数字 ############
print(re.search("\w+","343fsdf@$#^%%^ #$#-="))  #结果为:343fsdf

############ \W 只匹配特殊字符 ############
print(re.search("\W+","343fsdf@$#^%%^ #$#-="))  #结果为:@$#^%%^ #$#-=

# ############ \s 匹配\r \n \t 字符 ############
print(re.search("\s+","343fsdf  @$#^%%^#$#-=  \n\t\r"))  #结果为:  一个tab距离
print(re.findall("\s+","343fsdf @$#^%%^#$#-=  \n\t\r"))  #结果为:[' ', '  \n\t\r']

############ (?P<>[]{} <>[]{}...)分组匹配 ############
print(re.search("(?P[0-9]{6})(?P[0-9]{4})(?P[0-9]{4})","140426199306143242").groupdict("city"))
print(re.search("(?P<来自城市>[0-9]{6})(?P<生日年份>[0-9]{4})(?P<生日日期>[0-9]{4})","140426199306143242").groupdict("city"))
    '''
    结果
    {'birthday_year': '1993', 'from_provinces': '371481', 'birthday_date': '0614'}
    {'生日日期': '0614', '生日年份': '1993', '来自城市': '371481'}
    '''

五个套路

最常用的匹配语法:
re.match()      从字符串开头开始匹配,加不加^ 没有关系;
re.search()     从整个文本里去搜索匹配,匹配到第一个就返回了;
re.findall()    从整个文本里去索索匹配,匹配到所有结果返回;
re.split()      从整个文本里去用".." 去分割;(双引号里可以为任意值,除特殊字符)
re.sub()        在整个文本里去替换

flag的集中方法:
1、flags=re.I (re.IGNORECASE)    忽略大小写(括号内是完整写法)
2、flags=re.M (re.MULTILINE)     多行模式,改变"^"和"$"的行为(括号内是完整写法)
3、flags=re.S (re.DOTALL)        改变 点 的默认匹配,匹配任意字符 包括换行

套路补充练习

############ split 分割 ############
print(re.split("[0-9]","abc343dfd343dfd343df"))     #结果为:['abc', '', '', 'dfd', '', '', 'dfd', '', '', 'df']
print(re.split("[0-9]+","abc343dfd343dfd343df"))    #结果为:['abc', 'dfd', 'dfd', 'df']

############ sub 替换 ############
#替换所有的数字为@
print(re.sub("[0-9]","@","abc343dfd343dfd343df"))           #结果为:abc@@@dfd@@@dfd@@@df
#替换前两个匹配的数字为@
print(re.sub("[0-9]","@","abc343dfd343dfd343df",count=2))    #结果为:abc@@3dfd343dfd343df
#替换前两次匹配的数字为@
print(re.sub("[0-9]+","@","abc343dfd343dfd343df",count=2))   #结果为:abc@dfd@dfd343df

############ flag方法匹配方法 flags=re.I ############
print(re.search("[a-z]+","abcdABCD",flags=re.I))

############ flag方法匹配方法 flags=re.M ############
#匹配开头以a开始的,不加flags=re.M 匹配不成功
print(re.search("^a","\nabc\neee"))
#匹配开头以a开始的,加flags=re.M 匹配成功
print(re.search("^a","\nabc\neee",flags=re.M))      #结果为:<_sre.SRE_Match object; span=(1, 2), match='a'>
#匹配开头以eee开始的,加flags=re.M 匹配成功
print(re.search("^eee","\nabc\neee",flags=re.M))    #结果为:<_sre.SRE_Match object; span=(5, 8), match='eee'>

############ flag方法匹配方法 flags=re.S ############
#匹配任意字符  没有加flags=re.S 匹配显示不出\n
print(re.search(".+","\nabc\neee"))             #结果为:<_sre.SRE_Match object; span=(1, 4), match='abc'>
#匹配任意字符  加flags=re.S 匹配显示出\n
print(re.search(".+","\nabc\neee",flags=re.S))  #结果为:<_sre.SRE_Match object; span=(0, 8), match='\nabc\neee'>

############ **匹配IP地址** ############
a = "df99.99.99.255l127.0.0.2d255.255.255.256r0.1.1.1t1.0.0.0rtjk1.12.22.22jks8.8.8.8j0.0.0.1f1298.298.298.298kd23998.886.88e1.1.1.1t6.88613121.1.1.178798$%255.255.255.255#$%192.168.1.11hfsdn3.3.3.3fdf68734343"
b = "df5lddd127.0.0.2fdf6r0.1.1.1trtjkjksj0.0.0.1f1298.298.298.298kd23998.886.88et6.8861378798$%#$%hfsdnfdf68734343"

print(re.findall("[0-1]{0,1}[1-9]{1,2}\.[0-1]{0,1}[0-9]{0,2}\.[0-1]{0,1}[0-9]{0,2}\.[0-1]{0,1}[0-9]{0,2}|[1-9]{1,3}\.2[0-5]{0,2}\.2[0-5]{0,2}\.2[0-5]{0,2}",a))

print(re.findall("[0-1]{0,1}[1-9]{1,2}\.[0-1]{0,1}[0-9]{0,2}\.[0-1]{0,1}[0-9]{0,2}\.[0-1]{0,1}[0-9]{0,2}|[1-9]{1,3}\.2[0-5]{0,2}\.2[0-5]{0,2}\.2[0-5]{0,2}",b))

'''
匹配ip地址结果:
['99.99.99.25', '127.0.0.2', '255.255.255.25', '1.0.0.0', '1.12.22.22', '8.8.8.8', '1.1.1.1', '121.1.1.178', '255.255.255.255', '192.168.1.11', '3.3.3.3']
['127.0.0.2']
'''