python-正则

python之正则表达式:

#!/usr/bin/python3
# coding:utf-8
# Auther:AlphaPanda
# Description:正则表达式
# Version:q
# Date:Mon Dec  2 11:17:58 EST 2019
# 导入相关模块
import re
"""
语法:把字符串按照正则表达式进行匹配,把匹配到的结果返回到列表中
lst = re.findall(正则表达式,字符串)
"""
# 1) 预定义字符集
# \d 匹配数字 
res = re.findall("\d","adsf123asdfa")
print(res,type(res))
# \D 匹配非数字
print(re.findall("\D","asdfa#@$123sdf"))
# \w 匹配字母数字下划线
print(re.findall("\w","asdfas123%^&_sdf"))
# \W 匹配非字母非字母和非下划线的其他字符
print(re.findall("\W","asdfas123%^&_sdf"))
# \s 匹配任意的空白符(空白符包括\n换行符,\t指标符,\r回车符??)
print(re.findall("\s","""abcd adf
like    you"""))
# \S 匹配任意的非空白符
print(re.findall("\S","""abcd adf
like    you"""))
# \n 匹配换行符
print(re.findall("\n","""abcd adf
like    you"""))
# \t 匹配制表符
print(re.findall("\t","""abcd adf
like    you"""))


### 2)字符组[]匹配中括号内列举的字符,从[abc]三个中选一个
lst = re.findall("[abc]","pouiuaqe4b24c")
print(lst)
print(re.findall('a[abc]b','aab abb acb adb')) # aab abb acb
print(re.findall('a[0-9]b','a1b a2b a3b acb ayb')) #a1b a2b a3b
print(re.findall('a[a-z]b','a1b a2b a3b acb ayb adb')) #acb ayb adb
print(re.findall('a[A-Z]b','a1b a2b a3b  aAb aDb aYb')) # aAb aDb aYb
print(re.findall('a[0-9a-zA-Z]b','a-b aab aAb aWb aqba1b')) # aab aAb aWb aqb a1b
# 优化 [0-9a-zA-Z] => [0-z]  可以匹配到特殊的字符,不是单纯的数字和字母
print(re.findall('a[0-z]b','a-b aab aAb aWb a@ba1b'))  # ['aab', 'aAb', 'aWb', 'a@b', 'a1b']
# ^ 除了 : 除了+ - * / 之外的所有字符都匹配
print(re.findall('a[^-+*/]b',"a%b ccaa*bda&bd")) # a%b a&b
# 如果就想匹配^或者-符号,使用\进行转义
print(re.findall("a[\^\-]b","a^b a-b a*b"))
# 匹配 \
lst = re.findall(r"a\\b",r"a\b")
print(lst)  ##['a\\b'] 显示问题
res = lst[0]
print(res)


### 多个字符匹配   
# 1 量词练习:
# ?匹配0个或者是1个?前面的字符串  例如a?  
print(re.findall("a?b","abaabaaabbbasdf")) # ['ab', 'ab', 'ab', 'b', 'b']
# + 匹配一个或者多个+前面的字符串
print(re.findall("a+b","abaabaaabbbasdf")) # ['ab', 'aab', 'aaab']
# * 匹配0个或则多个*前的字符串
print(re.findall("a*b","abaabaaabbbasdf")) # ['ab', 'aab', 'aaab', 'b', 'b']
# {m,n} 匹配m个至n个中括号前的字符串
print(re.findall("a{1,5}b","abaabaaabbbasdf"))
# {m,} 匹配至少出现m次大括号前面的字符串
print(re.findall("a{1,}b","baabaaabccccaaa"))


### 贪婪模式和非贪婪模式
"""
贪婪模式:匹配字符串时,默认向更多次进行匹配(回溯算法)、
非贪婪模式:匹配字符串时,默认向更少次匹配

回溯算法:从左到右依次进行匹配,直到最后再也匹配不到了,回头,找离右侧最近的字符返回

. 匹配除换行符(\n、\r)之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用像"(.|\n)"的模式。
贪婪模式:
.? .+ .* .{m,n}
非贪婪模式:
.?? .+? .*? .{m,n}?
"""
# 贪婪模式:
strvar = "刘能和刘老根和刘铁棍子123子"
res = re.findall("刘.",strvar)
print(res)
# 默认向更多次匹配
lst = re.findall("刘.?",strvar)
print(lst)
lst = re.findall("刘.+",strvar)
print(lst)
lst = re.findall("刘.*",strvar)
print(lst)
lst = re.findall("刘.{1,21}",strvar)
print(lst)
lst = re.findall("刘.{1,21}子",strvar)
print(lst)

# 非贪婪模式
# 默认向更少次匹配
lst = re.findall("刘.??",strvar)
print(lst)
lst = re.findall("刘.+?",strvar)
print(lst)
lst = re.findall("刘.*?",strvar)
print(lst)
lst = re.findall("刘.{1,21}?",strvar)
print(lst)
lst = re.findall("刘.{1,21}?子",strvar)
print(lst)



### 3 边界符:
#    卡住左边界 \bw
#    卡住右边界 d\b
strvar = "word pwd appp"
lst = re.findall(r"\bw.*?",strvar)
print(lst)
lst = re.findall(r"\bw.*? ",strvar)
print(lst)
lst = re.findall(r"\bw.* ",strvar)
print(lst)
# 匹配word单词的方法
# 方法一:
lst = re.findall(r"\bw.*?d\b",strvar)
print(lst)
# 方法二:
lst = re.findall(r"\bw\S*",strvar)
print(lst)
# 匹配以w为左边界,往右开使匹配尽量多非空字符,由于贪婪模式,因此会返回匹配到的第一个空字符前面所有的字符


# 4 ^ 以...开头  $ 以...结尾
"""
如果出现了^ 或者$,意味着把这个字符串当成一个整体匹配
"""
strvar = "大哥大嫂大爷"
print(re.findall('大.',strvar))
print(re.findall('^大.',strvar))
print(re.findall('大.$',strvar))
print(re.findall('^大.$',strvar))  # 返回空列表,以大开头之后有一个字符结尾  
print(re.findall('^大.*?$',strvar))
print(re.findall('^大.*?$',"大哥大嫂大爷 as"))
print(re.findall('^g.*? ' , 'giveme 1gfive gay'))
print(re.findall('five$' , 'aassfive'))
print(re.findall('^giveme$' , 'giveme'))
print(re.findall('^giveme$' , 'giveme giveme'))
print(re.findall("^g.*e",'giveme 1gfive gay'))



#### 正则表达式分组
# 分组:使用()表达一个整体, (?:正则表达式)表示取消优先显示的功能
print(re.findall('.*_good','wusir_good alex_good secret男_good'))
print(re.findall('.*?_good','wusir_good alex_good secret男_good'))
# 优先显示括号内容
print(re.findall('(.*?)_good','wusir_good alex_good secret男_good'))
# 取消优先显示内容
print(re.findall('(?:.*?)_good','wusir_good alex_good secret男_good'))

# | 代表或,a|b 匹配字符a或者匹配字符b. 把字符串长的写在前面,字符串短的写在后面
strvar = "abckjkjabcd"
lst = re.findall("abc|abcd",strvar)
print(lst)

lst = re.findall("abcd|abc",strvar)
print(lst)

# 匹配小数
strvar = "3.12 .234 asdf 0.23 34 56 -- ..."
lst = re.findall(r"\d+\.\d+",strvar)
print(lst)

# 匹配小数和整数
lst = re.findall(r"\d+\.\d+|\d+",strvar)
print(lst)

# 用分组的形式匹配
lst = re.findall(r"\d+(?:\.\d+)?",strvar)
print(lst)

# 匹配135或者171的手机号
strvar = "13523456079,17198453627,13534342342"
lst = re.findall(r"135\d{8}|171\d{8}",strvar)
print(lst)
lst = re.findall(r"135\d{8}|171\d{8}","17166668888,13566668888,13999992332")
print(lst)
lst = re.findall(r"^135\d{8}$","13523234545")
print(lst)

# 正则函数search
"""
obj = re.serach(正则表达式,字符串)
search  匹配到一个就立刻返回,返回一个对象
        可以让分组里面的内容和匹配到的内容同时显示
findall 匹配到所有就返回,返回一个列表
        不可以让分组的内容和匹配到的内容同时显示
search 匹配出来的结果
    (1)group这个方法获取
    (2)groups 一次性获取所有小括号中匹配到的内容
"""

obj = re.search(r"^135\d{8}$|^171\d{8}","17166668888")
print(obj)
res = obj.group()
print(res)

# 匹配www.baidu.com或者是www.oldboy.com
strvar = " www.baidu.com "
obj = re.search(r"(www)\.(baidu|oldboy)\.(com)",strvar)
res = obj.group()
print(res)
# 获取第一个小括号中的内容
res = obj.group(1)
print(res)
# 获取第二个小括号中的内容
res = obj.group(2)
print(res)
# 获取第三个小括号中的内容
res = obj.group(3)
print(res)

# 案例:"5*6-7/3" 匹配5*6或者是7/3 计算最后的结果
strvar = "5*6-7/3"
obj = re.search(r"\d[*/]\d",strvar)
print(obj.group())
# 匹配5*6
res1 = obj.group()
print(res1,type(res1))

# 计算5*6
def calc(strvar):
    if "*" in strvar:
        a,b = strvar.split("*")
        return float(a) * float(b)
    elif "/" in strvar:
        a,b = strvar.split("/")
        return float(a) / float(b)
res = calc(res1)
print(res)

# 把结果替换回原来的字符
strvar1 = strvar.replace("5*6",str(res))
print(strvar1,"1")

# 再去提取7/3
obj = re.search(r"\d[*/]\d",strvar1)
res1 = obj.group()
print(res1,type(res1),"2")

# 计算7/3=2.33333333
res1 = calc(res1)
print(res1,"3")

# 把结果替换回原来的字符串
strvar2 = strvar1.replace("7/3",str(res1))
print(strvar2,type(strvar2),"(4")
strvar2="30.0-2.3333333333333335"
# 带有符号的小数或者整数
#lst = re.findall(r"[+-]?\d+(?:\.d+)?",strvar2)
#print(lst)
lst = re.findall(r"[+-]?\d+(?:\.\d+)?",strvar2)
# [+-]?\d+(?:\.\d+)?
# 小数: \d+\.\d+
# 整数:\d+
# 整数或者小数 \d+(\.\d+)?
# 实数  [+-]?\d+(?:\.\d+)?
print(lst)
total = 0
for i in lst:
    total += float(i)
print(total)

 

上一篇:Day11 Python学习笔记&关键注意点


下一篇:Python爬虫实践 ——— Regular Expressions Python re模块