0730Python总结-正则表达式

一.正则表达式-单个字符的匹配

import re
findall(正则表达式,字符串) 把符合正则表达式的字符串存在列表中返回
re.findall

1.预定义字符集

\d 匹配数字

strvar = "sdfsdf*(&*(&(2ui3"
lst = re.findall("\d", strvar)
print(lst)  # ['2', '3']

\D 匹配非数字

strvar = "sdfsdf*(&*(&(2ui3"
lst = re.findall("\D", strvar)
print(lst)  # ['s', 'd', 'f', 's', 'd', 'f', '*', '(', '&', '*', '(', '&', '(', 'u', 'i']

\w 匹配字母数字下划线

strvar = "sadf*)(*_)456你你好"
lst = re.findall("\w", strvar)
print(lst)  # ['s', 'a', 'd', 'f', '_', '4', '5', '6', '你', '你', '好']

\W 匹配非字母或数字或下划线

strvar = "sadf*)(*_)456你你好"
lst = re.findall("\W", strvar)
print(lst)  # ['*', ')', '(', '*', ')']

\s 匹配任意的空白符 (\n \t \r " ")

strvar = "     				 "
lst = re.findall("\s", strvar)
print(lst)  # [' ', ' ', ' ', ' ', ' ', '\t', '\t', '\t', '\t', ' ']

\S 匹配任意非空白符

strvar = "    abdd 						"
lst = re.findall("\S", strvar)
print(lst)  # ['a', 'b', 'd', 'd']

\n 匹配一个换行符

strvar = """

"""
lst = re.findall("\n", strvar)
print(lst)  # ['\n', '\n']

\t 匹配一个制表符

strvar = """
			
"""
lst = re.findall(r"\t", strvar)
print(lst)  # ['\t', '\t', '\t']
2.字符组[] 必须从字符组列举出来的字符当中抽取,默认一个,如果没有返回空
strvar = "abpoiuc"
lst = re.findall("[abc]", strvar)
print(lst)  # ['a', 'b', 'c']

print(re.findall("a[abc]b", "aab abb acb adb"))  # ['aab', 'abb', 'acb']
print(re.findall("a[0123456789]b", "a1b a2b a3b acb ayb"))  # ['a1b', 'a2b', 'a3b']
# -代表到,代表的是范围
# 0-9 0到9这么多的数字
print(re.findall("a[0-9]b", "a1b a2b a3b acb ayb"))  # ['a1b', 'a2b', 'a3b']
# a-g => abcdefg
print(re.findall("a[abcdefg]b", "a1b a2b a3b acb ayb adb"))  # ['acb', 'adb']
print(re.findall("a[a-g]b", "a1b a2b a3b acb ayb adb"))  # ['acb', 'adb']
# a-z => 26个小写字母
print(re.findall("a[a-z]b", "a1b a2b a3b acb ayb adb"))  # ['acb', 'ayb', 'adb']

print(re.findall("a[0-9a-zA-Z]b", "a-b aab aAb aWb aqba1b"))  # ['aab', 'aAb', 'aWb', 'aqb', 'a1b']
# 0-z 不会单纯的匹配小写大小字母和数字,还会匹配到特殊的符号,比如_和@
print(re.findall("a[0-z]b", "a_ba@b aab aAb aWb aqba1b"))  # ['a_b', 'a@b', 'aab', 'aAb', 'aWb', 'aqb', 'a1b']


print(re.findall("a[0-9][*#/]b", "a1/b a2b a29b a56b a456b"))  # ['a1/b']
# ^ 除了, 子字符组当中,开头的位置使用
print(re.findall("a[^-+*/]b", "a%b ccaa*bda&bd"))  # ['a%b', 'a&b']

# 如果想要匹配^ ,需要前面加上\进行转义
lst = re.findall("a[\^\-]b", "a+b a-b a^b")
print(lst)  # ['a-b', 'a^b']

# 匹配 \
"""\b 本身也是转义字符:退格(把光标向左移动一位)"""
lst = re.findall(r"a\\b", r"a\b")
print(lst[0])  # a\b

二.正则表达式-多个字符的匹配

import re

1.量词

(1) ? 匹配0个或者1个a

print(re.findall("a?b", "abbzab abb aab"))  # ['ab', 'b', 'ab', 'ab', 'b', 'ab']

(2) + 匹配1个或者多个a

print(re.findall("a+b", "b ab aaaaaab abb"))  # ['ab', 'aaaaaab', 'ab']

(3) * 匹配0个或者多个a

print(re.findall("a*b", "b ab aaaaaab abbbbbbb"))  # ['b', 'ab', 'aaaaaab', 'ab', 'b', 'b', 'b', 'b', 'b', 'b']

(4) {m,n} 匹配m个至n个a

# 1 <= x <= 3
print(re.findall("a{1,3}b", "aaab ab aab abbb aaz aabb"))  # ['aaab', 'ab', 'aab', 'ab', 'aab']
# {2,} 至少2次
print(re.findall("a{2,}b", "aaab ab aab abbb aaz aabb"))  # ['aaab', 'aab', 'aab']
# {2} 必须2次
print(re.findall("a{2}b", "aaab ab aab abbb aaz aabb"))  # ['aab', 'aab', 'aab']
2.贪婪匹配和非贪婪匹配
贪婪匹配:  默认向更多次数匹配(回溯算法) .* .+
非贪婪匹配:  默认向更少次数匹配  .*?  .+?

在量词的后面加 ?
.??  .+?  .*?  {4,}?

回溯算法: 从左向右进行匹配,直到匹配到最后,再也找不到,回头,找最后一个(递归)

 .  匹配任意字符,除了换行符\n
strvar = "刘能和刘老根和刘铁柱子111子222"
lst = re.findall("刘.", strvar)
print(lst)  # ['刘能', '刘老', '刘铁']

lst = re.findall("刘.?", strvar)
print(lst)  # ['刘能', '刘老', '刘铁']

lst = re.findall("刘.+", strvar)
print(lst)  # ['刘能和刘老根和刘铁柱子111子222']

lst = re.findall("刘.*", strvar)
print(lst)  # ['刘能和刘老根和刘铁柱子111子222']

lst = re.findall("刘.{4,}子", strvar)
print(lst)  # ['刘能和刘老根和刘铁柱子111子']
# 非贪婪匹配
lst = re.findall("刘.??", strvar)
print(lst)  # ['刘', '刘', '刘']

lst = re.findall("刘.+?", strvar)
print(lst)  # ['刘能', '刘老', '刘铁']

lst = re.findall("刘.*?", strvar)
print(lst)  # ['刘', '刘', '刘']

lst = re.findall("刘.{4,}?子", strvar)
print(lst)  # ['刘能和刘老根和刘铁柱子']
3.边界符 \b
\b 本身也是转义字符:退格(把光标向左移动一位)
word
右边界: d\b
左边界: \bw
# 右边界
strvar = "word pwd scf"
lst = re.findall(r"d\b", strvar)
print(lst)  # ['d', 'd']

lst = re.findall(r".*d\b", strvar)
print(lst)  # ['word pwd']

lst = re.findall(r".*?d\b", strvar)
print(lst)  # ['word', ' pwd']

# 左边界
lst = re.findall(r"\bw", strvar)
print(lst)  # ['w']

# 要所有w开头的单词
lst = re.findall(r"\bw.*", strvar)
print(lst)  # ['word pwd scf']

lst = re.findall(r"\bw.*?", strvar)
print(lst)  # ['w']

lst = re.findall(r"\bw.* ", strvar)
print(lst)  # ['word pwd ']

lst = re.findall(r"\bw.*? ", strvar)
print(lst)  # ['word ']
# lst = re.findall(r"w\S*", strvar)
# print(lst)  # ['word', 'wd']

# \S 匹配的是非空白符
lst = re.findall(r"\bw\S*", strvar)
print(lst)  # ['word']
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("^大.*?大$", strvar))  # []
print(re.findall("^大.*?爷$", strvar))  # ['大哥大嫂大爷']
print(re.findall("^g.*? ", "giveme 1gfive gay"))  # ['giveme ']
print(re.findall("five$", "aassfive"))  # ['five']
print(re.findall("^giveme$", "giveme"))  # ['giveme']
print(re.findall("^giveme$", "giveme giveme"))  # []
print(re.findall("giveme", "giveme giveme"))  # ['giveme', 'giveme']
print(re.findall("^g.*e", "giveme 1gfive gay"))  # ['giveme 1gfive']

三.正则表达式-匹配分组()

import re

# 分组练习(圆括号)
print(re.findall(".*?_good", "wusir_good alex_good secret男_good"))  # ['wusir_good', ' alex_good', ' secret男_good']
# () 优先显示括号里面的内容
print(re.findall("(.*?)_good", "wusir_good alex_good secret男_good"))  # ['wusir', ' alex', ' secret男']
# ?: 取消显示括号里面的内容
print(re.findall("(?:.*?)_good", "wusir_good alex_good secret男_good"))  # ['wusir_good', ' alex_good', ' secret男_good']
# | 代表或, a|b 匹配字符a 或者 匹配字符b 把字符串长的写在前面,字符串短的写在后面
strvar = "abcdefg"
lst = re.findall("a|b", strvar)
print(lst)  # ['a', 'b']

"""在使用的时候,把不容易匹配到的字符串放到前面,把容易匹配到的放到后面"""
strvar = "abciuiuabcdwerewr"
lst = re.findall("abc|abcd", strvar)  # ['abc', 'abc']
lst = re.findall("abcd|abc", strvar)  # ['abc', 'abcd']
print(lst)
 *. 除了\n,匹配所有字符
 \. 代表的. 这个字符本身,不转义* 

strvar = ".34 … 78. 78.12 56.3 .3 .4 .5 "

匹配小数

lst = re.findall(r"\d+\.\d+", strvar)
print(lst)  # ['78.12', '56.3']

匹配小数和整数

lst = re.findall(r"\d+\.\d+|\d+", strvar)
print(lst)  # ['34', '78', '78.12', '56.3', '3', '4', '5']

分组来表达小数和整数

lst = re.findall(r"\d+(\.\d+)?", strvar)
print(lst)  # ['', '', '.12', '.3', '', '', '']

lst = re.findall(r"\d+(?:\.\d+)?", strvar)
print(lst)  # ['34', '78', '78.12', '56.3', '3', '4', '5']

匹配135或171的手机号

strvar = "13566668888 17166668888"
lst = re.findall(r"(?:135|171)\d{8}", strvar)
print(lst)  # ['13566668888', '17166668888']

# 用^$ 卡死长度,只能是一个手机号,不能是多个
strvar = "13566668888"
lst = re.findall(r"^(?:135|171)\d{8}$", strvar)
print(lst)  # ['13566668888']

匹配www.baidu.com 或者 www.oldboy.com

strvar = "www.baidu.com www.lagou.com www.oldboy.com"
lst = re.findall(r"(?:www).(?:baidu|oldbay).(?:com)", strvar)
print(lst)  # ['www.baidu.com']
findall  是把所有符合条件的内容都匹配出来放到列表里
         不能够把匹配到的结果和分组当中的内容显示在同一界面当中

search	  按照正则表达式,把第一次匹配到的内容返回出来,返回的是对象
          能够把匹配到的结果和分组当中的内容显示在同一界面当中
          
对象.group  返回的是匹配到的结果
对象.groups  返回的是括号分组里面的内容

如果匹配不到内容,返回的是None,无法调用group 或者groups方法的

search 的用法

strvar = "www.baidu.com www.lagou.com www.oldboy.com"
obj = re.search(r"www\.(baidu|oldbay)\.(com)", strvar)

# 返回的是匹配的结果
res = obj.group()
print(res)  # www.baidu.com

# 通过group和下标可以获取到括号的内容(了解)
print(obj.group(1))  # baidu
print(obj.group(2))  # com


# 返回的是括号分组里面的内容
res = obj.group()
print(res)  # www.baidu.com

"56-7/3" 匹配 56 或者 7/3 算出最后的结果

strvar = "5*6-7/3"

# 匹配5*6
obj = re.search(r"\d+[*/]\d+", strvar)
print(obj)  # <_sre.SRE_Match object; span=(0, 3), match='5*6'>
strvar1 = obj.group()
print(strvar1, type(strvar1), "====")  # 5*6 <class 'str'> ====


# 计算5*6
num1, num2 = strvar1.split("*")
print(num1, num2)  # 5 6
strvar2 = str(int(num1) * int(num2))
print(strvar2, type(strvar2))  # 30 <class 'str'>

# 替换5*6 为字符串30
strvar3 = strvar.replace(strvar1, strvar2)
print(strvar3, type(strvar3))  # 30-7/3 <class 'str'>


# 匹配7/3
obj = re.search(r"\d+[*/]\d+", strvar3)
print(obj)  # <_sre.SRE_Match object; span=(3, 6), match='7/3'>
strvar4 = obj.group()
print(strvar4)  # 7/3

# 计算7/3
num1, num2 = strvar4.split("/")
strvar5 = str(int(num1) / int(num2))
print(strvar5, type(strvar5))   # 2.3333333333333335 <class 'str'>

# 替换7/3为字符串2.3333333333333335
strvar6 = strvar3.replace(strvar4, strvar5)
print(strvar6, type(strvar6))

# 计算30-2.3333333333333335 得出最后的结果
num1, num2 = strvar6.split("-")
res = float(num1) - float(num2)
print(res)

四.命名分组

import re

strvar = "<div>今天天气不错~<div>"
lst = re.findall("<.*?>(.*?)<(.*?)>", strvar)
print(lst)  # [('今天天气不错~', 'div')]

反向引用: 匹配到的值,再引用一次
“”"\1 把第一个小括号里面的内容,拿出来再匹配一次"""

lst = re.findall(r"<(.*?)>(.*?)<(/\1)>", strvar)
print(lst)

\1 代表反向引用第一个括号 \2代表反向引用第二个括号

strvar = "a1b2cab"
obj = re.search(r"(.*?)\d(.*?)\1\2", strvar)
print(obj)

获取匹配到的内容
r

es1 = obj.group()
print(res1)

获取分组里面的内容

res2 = obj.groups()
print(res2)
# 命名分组
"""
 (?P<组名>正则表达式) 给这个组起一个名字
 (?P=组名) 引用之前组的名字,把该组名匹配到内容放到当前位置
"""
# 方法一
strvar = "a1b2cab"
obj = re.search(r"(?P<tag1>.*?)\d(?P<tag2>.*?)\d(?P<tag3>.*?)\1\2", strvar)
# 获取匹配到的内容
res1 = obj.group()
print(res1)
# 获取分组里面的内容
res2 = obj.groups()
print(res2)
# 方法二
strvar = "a1b2cab"
obj = re.search(r"(?P<tag1>.*?)\d(?P<tag2>.*?)\d(?P<tag3>.*?)(?P=tag1)(?P=tag2)", strvar)
# 获取匹配到的内容
res1 = obj.group()
print(res1)
# 获取分组里面的内容
res2 = obj.groups()
print(res2)

猜你喜欢

转载自blog.csdn.net/qq_45957580/article/details/107738410