三. python的re模块

一 .re模块正则表达式
# 在线正则表达式    http://tool.chinaz.com/regex/

1. 正则表达式基础
    简单介绍
    正则表达式并不是Python的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大。得益于这一点,在提供了正则表达式的语言里,正则表达式的语法都是一样的,区别只在于不同的编程语言实现支持的语法数量不同;但不用担心,不被支持的语法通常是不常用的部分。如果已经在其他语言里使用过正则表达式
,只需要简单看一看就可以上手了。

2. re模块
2.1. 开始使用re
Python通过re模块提供对正则表达式的支持。
使用re的一般步骤是先将正则表达式的字符串形式编译为Pattern实例,
然后使用Pattern实例处理文本并获得匹配结果(一个Match实例),
最后使用Match实例获得信息,进行其他的操作。
# 给段字符串判断是否是手机号码

def aa(str):
  if len(str)!=11:
     return False
  elif str[0]!="1":
    return False
  elif str[1:3]!="39" and str[1:3]!="31":
    return False

  for i in range(3,11):
      if str[i]<"0" or str[i]>"9":
         return False

  return True

age=input("请输入你的电话号码:")
n=aa(age)

print(n)
import re
re.match函数
  原型: match(pattern,string,flags=0)
      pattern :匹配的正则表达式(匹配格式)
      string  :要匹配的字符串
      flages : 标志位  用于控制正则表达式的匹配方式
      re.I        忽略大小写
      re.L        做本地户识别
      re.M        多行匹配 影响 ^和$
      re.S        是.匹配任意包括换行符在内的所有字符
      re.U        根据  Unicode 字符集解析字符  影响 \w  \W  \b  \B
      re.X        使我们以更灵活的格式理解正则表达式

  参数:
功能:尝试从字符串的起始位置匹配一个模式如果不是起始位置
     成功的话,返回 None

re.match()

1.match()函数:尝试从字符串的起始位置匹配一个模式如果不是起始位置成功的话,返回 None

import re

# 例如:百度网址
a=re.match("www","www.baidu.com") 
      # <_sre.SRE_Match object; span=(0, 3), match='www'>
print(a)

print("***********************华丽的分割线***********************************")

b=re.match("wwW","www.baidu.com") 
print(b)  #  None   表示没有匹配上


print("***********************华丽的分割线***********************************")

c=re.match("wwW","www.baidu.com", flags=re.I) 
print(c)      # 不区分大小写   
     # <_sre.SRE_Match object; span=(0, 3), match='www'>
     

print("***********************华丽的分割线***********************************")

d=re.match("www","www.baidu.com").span() 
print(d)  (0, 3)  #可以得到匹配的位置

2.search()函数:扫描整个字符串 并且返回第一个成功的匹配

# re.search()函数

#       原型: reach(pattern,string,flags=0)
#                   pattern :匹配的正则表达式(匹配格式)
#                   string  :要匹配的字符串
#                   flages : 标志位  用于控制正则表达式的匹配方式

#       功能: 扫描整个字符串 并且返回第一个成功的匹配

import re

str="my name is love  and to bing love"
a=re.search("love",str)
print(a)  
 # <_sre.SRE_Match object; span=(11, 15), match='love'>

3.findall()函数

re.findall()函数

      原型: findall(pattern,string,flags=0)
                  pattern :匹配的正则表达式(匹配格式)
                  string  :要匹配的字符串
                  flages : 标志位  用于控制正则表达式的匹配方式

      功能: 扫描整个字符串 并返回结果列表

str="my name is love  and to bing love"

a=re.findall("love",str)
print(a)
#['love', 'love']

一. 元字符

import re

# .    匹配除换行符以外的任意字符
# [0123456789]  []是字符集合 表示匹配方括号中所包含的任意一个字符
# [love]        []  匹配 'l','o','v','e' 中任意字符
# [a-z]           匹配任意小写字母
# [A-Z]        匹配任意大写字母
# [0-9]        匹配任意数字 类似: [0123456789]
# [0-9a-zA-Z]  匹配任意的数字 字母包括大小写

# [0-9a-zA-Z_] 匹配任意的数字 字母包括大小写 和下划线

# [^love]      匹配除了love 这几个字母以外的所有字符  
                   # 中括号里的^称为托字符 表示不匹配集合中的字符


# [^0-9]     匹配所有的非数字字符

#\d          匹配所有数字  效果如同[0-9]

# \D         匹配非数字字符    效果如同[^0-9]

# \w         匹配数字 字母  下划线  效果如同[0-9a-zA-Z]

#  \W        匹配非数字 字母 和下划线     效果如同[^0-9a-zA-Z
  
#   \s       匹配任意的空白符   (换行   空格  回车  换页  制表) 
                                # 效果同 [\f \n \r \t]
                                
# \S              匹配任意的非空白符   效果同 [^\f \n \r \t]

str="my name is love  and to bing love"
a=re.search(".",str)
print(a)  
# <_sre.SRE_Match object; span=(0, 1), match='m'>
print("***********************华丽的分割线***********************************")


# [0123456789]  []是字符集合 表示匹配方括号中所包含的任意一个字符    
str="my name is love  an6d to bin5g love"
b=re.search("[0123456789]",str)
print(b)  
# <_sre.SRE_Match object; span=(19, 20), match='6'> 


print("***********************华丽的分割线***********************************")
# [love]        []  匹配 'l','o','v','e' 中任意字符
str="my name is love  and to bing love"
c=re.search("[love]",str)
print(c)  
# <_sre.SRE_Match object; span=(6, 7), match='e'>
import re

# .    匹配除换行符以外的任意字符

# [0123456789]  []是字符集合 表示匹配方括号中所包含的任意一个字符

# [love]        []  匹配 'l','o','v','e' 中任意字符

# [a-z]           匹配任意小写字母

# [A-Z]        匹配任意大写字母

# [0-9]        匹配任意数字 类似: [0123456789]

# [0-9a-zA-Z]  匹配任意的数字 字母包括大小写

# [0-9a-zA-Z_] 匹配任意的数字 字母包括大小写 和下划线

# [^love]      匹配除了love 这几个字母以外的所有字符  
                   # 中括号里的^称为托字符 表示不匹配集合中的字符

# [^0-9]     匹配所有的非数字字符

#\d          匹配所有数字  效果如同[0-9]

# \D         匹配非数字字符    效果如同[^0-9]


# \w         匹配数字 字母  下划线  效果如同[0-9a-zA-Z]

#  \W        匹配非数字 字母 和下划线     效果如同[^0-9a-zA-Z
  
#   \s       匹配任意的空白符   (换行   空格  回车  换页  制表) 
                                # 效果同 [\f \n \r \t]
                                
# \S              匹配任意的非空白符   效果同 [^\f \n \r \t]

str="my name is love  and to bing love"
a=re.search(".",str)
print(a)  
# <_sre.SRE_Match object; span=(0, 1), match='m'>
print("***********************华丽的分割线***************************")

# [0123456789]  []是字符集合 表示匹配方括号中所包含的任意一个字符    
str="my name is love  an6d to bin5g love"
b=re.search("[0123456789]",str)
print(b)  
# <_sre.SRE_Match object; span=(19, 20), match='6'> 


print("***********************华丽的分割线***********************************")
# [love]        []  匹配 'l','o','v','e' 中任意字符
str="my name is love  and to bing love"
c=re.search("[love]",str)
print(c)  
# <_sre.SRE_Match object; span=(6, 7), match='e'>

print("***********************华丽的分割线***********************************")
print("***********************华丽的分割线***********************************")

str="my nam9e is lo6ve  and 5to bing love"
d=re.findall("\d",str)
print(d)   #['9', '6', '5']

二 .锚点字符(边界字符)

import re

# 锚点字符(边界字符)

# ^  :表示行首匹配   和[^]意思不一样

# $ :   行尾匹配
#
#  \A   匹配字符串开始  它和^的区别 是   \A只匹配正个字符串的
  
#  \Z  匹配字符串的结束 它和$的区别是 \Z 只能匹配整个字符串的结束 即使在re.M模式下也不会匹配它的行尾                                                                                       #开头,即使在 re.M模式下也不会匹配它行的行首

# \b   匹配一个单词的边间 也就是指单词和空格的位置  

# \B  匹配非单词边界  


str="my name is love  and to bing love"
a=re.search("love$",str)
print(a)  

# <_sre.SRE_Match object; span=(29, 33), match='love'>


str="my name is love  and to bing love"
b=re.search("^my",str)
print(b)  
# <_sre.SRE_Match object; span=(0, 2), match='my'>
print("***********************华丽的分割线***************************")


str="my name is love  and to bing love\n my 哈哈哈 loer"
e=re.findall("^my",str,re.M)
print(e)  
# ['my']


print("***********************华丽的分割线***************************")

str="my name is love  and to bing love\n my 哈哈哈 love"
g=re.findall("love$",str,re.M)
print(g)   # ['love'] ['love']


str="my name is love  and to bing love\n my 哈哈哈 love"
f=re.findall("love\Z",str,re.M)
print(f)   #['love']


print("***********************华丽的分割线***************************")

str="my name is love  and to bing love my 哈哈哈 love"
h=re.search("lo\b",str,re.M)
print(h)   # None


str="my name is love  and to bing love my 哈哈哈 love"
j=re.search("lo\B",str,re.M)
print(j)   #<_sre.SRE_Match object; span=(11, 13), match='lo'>

三 .分组

# 分组: 

#      除了简单判断是否匹配之外 正则表达式还提取子串的功能 用()表示就是提取分组


print("***********************华丽的分割线***********************************")
import re

str1="010-12345678"
m=re.match(r"(\d{3})-(\d{8})",str1)

print(m.group(0))    # 010-12345678
print(m.group(1))    # 010
print(m.group(2))    # 12345678



str2="010-12345678"
v=re.match(r"(\d{3})-(\d{8})",str2)
# 使用序号获取对应组的信息 group (0) 一只代表的原始字符串
print(v.group(0))    # 010-12345678
print(v.group(1))    # 010
print(v.group(2))    # 12345678
print(v.groups())    #('010', '12345678')    查看匹配的各组的情况



print("**RRRR*********************华丽的分割线***********************************")


# 编译: 当我们使用正则表达式时 re 模块会干两件事

#      1 . 编译正则表达式 如果正则表达式 本身不合法 会报错

#      2. 用编译后的正则表达式去匹配对象


# compile(pattern,flages=0)

#        pattern :匹配的正则表达式(匹配格式)
#        
a=r"^1(([3578]\d)|(47))\d{8}$"

print(re.match(a,"13600000000"))
# 编译正则表对象
re_telephon=re.compile(a)

re_telephon.match("13600000000")     




正则函数
re.match(pattern,string,flags=0)                    re模块 调用
re_telephon.match(string)                            re 对象调用


re.search(pattern,string,flags=0)
re_telephon.search(string)




re.findall(pattern,string,flags=0)
re_telephon.findall(string)


re.finditer(pattern,string,flags=0)
re_telephon.finditer(string)


re.sub()
re_telephon.sub(string)


re.subn()
re_telephon.subn(string)




re.split(pattern,string,maxsplit=0,flags=0)
re_telephon.split(string,maxsplit=0)
import re


# 正则字符串切割

str1="my name is lover to 哈哈哈"

print(str1.split(" "))
# ['my', 'name', 'is', 'lover', 'to', '哈哈哈']

print(re.split(r" +",str1))
# ['my', 'name', 'is', 'lover', 'to', '哈哈哈']


# re.finditer函数 
#       原型: .finditer(pattern,string,flags=0)
#                   pattern :匹配的正则表达式(匹配格式)
#                   string  :要匹配的字符串
#                   flages : 标志位  用于控制正则表达式的匹配方式
#                   
#         功能:与fandall 类似扫描整个字符串  返回的是一个迭代器
#         
str3="my is zhangsan man!my a nice lisi man! my is av ery man" 
d=re.finditer(r"(my)",str3)


while True:
    try:
        l=next(d)
        print(d)
    except StopIteration as e:
        break 
# <callable_iterator object at 0x004F57B0>
# <callable_iterator object at 0x004F57B0>
# <callable_iterator object at 0x004F57B0>


# re模块 字符串替换和修改
# sub()  函数
# subn()
#      参数:sub(pattern,repl,string,count=0)  
#           subn(pattern,repl,string,count=0) 

#               pattern   :   匹配的正则表达式(匹配格式)

#               repl      :   指定的用来替换的字符串

#               string    :   目标字符串
 
#               count=0   :   最多替换次数
 
#               flages=0  :   标志位  用于控制正则表达式的匹配方式

#  功能: 在目标字符串中以正则表达式的规则匹配字符串,在把他们替换成指定的字符串 可以指定替换的次数 如果不指定 就替换所有的匹配字符串

# 区别:

# sub()  返回一个被指定替换的字符串
# subn()返回一个元组 第一是替换的字符串 ,第二个元素表被替换的次数


str5="my is a good good  man good "
print(re.sub(r"(good)","nice",str5))
# my is a nice nice  man

str6="my is a good good  man good and good hao to good"
print(re.sub(r"(good)","nice",str6,count=3))
# my is a nice nice  man nice and good hao to good


print("***********************华丽的分割线***********************************")


str6="my is a good good  man good "

print(re.subn(r"(good)","nice",str6))

print(type(re.subn(r"(good)","nice",str6)))

# ('my is a nice nice  man nice ', 3)

# <class 'tuple'>
四 .数量词
import re
   # zyx  n m是假设的


   # (xyz)  匹配小括号的xyz (作为一个整体去匹配) 
    

   # x?   匹配零个或者多个X            

   #  x*   匹配0个或者任意多个x    贪婪匹配 尽可能多匹配
 
   #  x+  匹配至少一个x

   # x{n}   去匹配确定n个x (n是一个非负数)

   # x{n,}  匹配至少n个x

    
   # x{n,m}  匹配至少n个最多m个x 注意:n<=m 
  
   # x|Y    匹配的是x或者y
   

print("***********************华丽的分割线***************************")

print(re.findall(r"(lover)","my name lover to boy  lover"))  #['lover']
# ['lover', 'lover']  

print("***********************华丽的分割线***************************")
print(re.findall(r"o?","my name lover to boy  lover"))
# [ 'o', '', '', '', '', '', 'o', '', '', 'o', '', '', '', '', 'o', '', '', '', '']

print("***********************华丽的分割线***************************")
print(re.findall(r"a*","aaaabbbba"))
# ['aaaa', '', '', '', '', 'a', ''] 
 
print("***********************华丽的分割线***************************")
print(re.findall(r"a+","aaaabbbbaAA"))    #['aaaa', 'a']  

print("***********************华丽的分割线***************************")
print(re.findall(r"a{3}","aaaabbbbaAA"))#['aaa']   


print("***********************华丽的分割线***************************")
print(re.findall(r"a{3,}","aaaabbbbaAAAAaaaaaaaAA"))
#['aaaa', 'aaaaaaa']


print("***********************华丽的分割线***************************")
print(re.findall(r"a{3,6}","aaaabbbbaAAAAaaaaaavaaaaaaaaAA"))
#['aaaa', 'aaaaaa', 'aaaaaa']



print("***********************华丽的分割线***************************")
print(re.findall(r"((l|L)over)","lover=====Lover"))
# [('lover', 'l'), ('Lover', 'L')]
五 .贪婪 与非贪婪
正则表达式通常用于在文本中查找匹配的字符串
Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),
总是尝试匹配尽可能多的字符;非贪婪则相反
总是尝试匹配尽可能少的字符。在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪。
>>> s="This is a number 234-235-22-423"
>>> r=re.match(".+(\d+-\d+-\d+-\d+)",s)
>>> r.group(1)
'4-235-22-423'
>>> r=re.match(".+?(\d+-\d+-\d+-\d+)",s)
>>> r.group(1)
'234-235-22-423'
>>>
正则表达式模式中使用到通配字,那它在从左到右的顺序求值时,会尽量“抓取”
满足匹配最长字符串,在我们上面的例子里面,“.+”会从字符 串的启始处抓取满足模式的最长字符,
其中包括我们想得到的第一个整型字段的中的大部分,“\d+”只需一位字符就可以匹配,所以它匹配了数字“4”,而“.+”则匹配了
从字符串起始到这个第一位数字4之前的所有字符。
解决方式:非贪婪操作符“?”,这个操作符可以用在"*","+","?"的后面,要求正则匹配的越少越好
>>> re.match(r"aa(\d+)","aa2343ddd").group(1)
'2343'
>>> re.match(r"aa(\d+?)","aa2343ddd").group(1)
'2'
>>> re.match(r"aa(\d+)ddd","aa2343ddd").group(1) 
'2343'
>>> re.match(r"aa(\d+?)ddd","aa2343ddd").group(1)
'2343'
>>>
import re

# 需求: 
srt="my is a good man!my is a niace man! my is a very handsome man"
print(re.findall(r"^my(.*?)man$",srt))

print("***********************华丽的分割线***************************")

# *? +? x?  最小匹配 通常都是尽可能多的匹配 可以使用这种可以解决贪婪模式

(?:x)     类似(xyz) 但是不表示 一个组
案例
import re

# 给段字符串判断是否是手机号码

def aa(str):
  if len(str)!=11:
     return False
  elif str[0]!="1":
    return False
  elif str[1:3]!="39" and str[1:3]!="31":
    return False

  for i in range(3,11):
      if str[i]<"0" or str[i]>"9":
         return False

  return True

age=input("请输入你的电话号码:")
n=aa(age)

print(n)



def cc(str):
    # "13912345678"
    
    
    a=r"^1(([3578]\d)|(47))\d{8}$"
    
    
    res=re.match(a,str)
    
    
    return res
    
  
print(cc("13912345678"))
 QQ    : 1837855846

 mail  :   loveraa@163.com

 phone :   010-55348765

 user :

  ip :

 url :  

# QQ正则
 re_QQ=re.compile(r"^[1-9]\d{5,9}$")
 print(re_QQ.search("1234567890"))


re.compile() 函数
编译正则表达式模式,返回一个对象。可
以把常用的正则表达式编译成正则表达式对象,方便后续调用及提高效率。

 

 










 
posted @ 2019-05-13 01:16  supreme9999  阅读(373)  评论(0编辑  收藏  举报