d15 常用模块之正则模块

正则:

正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。

(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

正则就是用来筛选字符串中的特定的内容的

正则表达式与re模块的关系

   1.正则表达式是一门独立的技术,任何语言均可使用
   2.python中要想使用正则表达式需要通过re模块
View Code

验证手机号

# 纯python代码校验
while True:
    num= input('number>>>:')
    if len(num) == 11 and num.startswith('13')and num.isdigit()
        or num.startswith('15')and num.isdigit()
        or num.startswith('18')and num.isdigit()
        or num.startswith('19')and num.isdigit():
        print('合法号码')
    else:
        print('号码不正确')
View Code
#正则表达式
import re
number = input('number>>>:')
if re.match('^(13|15|18|19)[0-9]{9}$',number):
    print('合法号码')
else:
    print('号码不正确')
View Code

正则的应用场景:

1.爬虫

2.数据分析

正则表达式在线测试网址

http://tool.chinaz.com/regex/

在网址中只要有reg...一般情况下都是跟正则有关

正则

元字符

量词

 

 

[ ]  字符组

一个字符串里面的表达式都是或的关系

^与$连用

会精准限制匹配的内容
两者中间写什么 匹配的字符串就必须是什么
多一个也不想少一个也不行

| 或

abc|ab 一定要将长的放在前面

[^]

 除了[]写的字符 其他都要

 .^$

*+?{}

字符集[] {}

分组() 与 | [^]

分组:当多个正则符号需要重复多次的时候或者当做一个整体进行其他操作,那么可以分组的形式
    分组在正则的语法中就是()

 转义

如果匹配一次" ",字符串中要写成' '

如果匹配一次" ",字符串中要写成'n'

贪婪匹配

 

 几个常用的非贪婪匹配Pattern

*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复
正则在匹配的时候默认都是贪婪匹配(尽量匹配多的)
你可以通过在量词后面加上一个?就可以将贪婪匹配变成非贪婪匹配(惰性匹配)

.*?的用法

. 是任意字符
* 是取 0 至 无限长度
.? 是非贪婪模式。
何在一起就是 取尽量少的任意字符,一般不会这么单独写,他大多用在:
.*?x

就是取前面任意长度的字符,直到一个x出现
量词必须跟在正则符号的后面
量词只能能够限制紧挨着它的那一个正则符号
<.*>:先拿着里面的.*去匹配所有的内容,然后再根据>往回退着找,遇到即停止
<.*?>:先拿着?后面的>去匹配符合条件的最少的内容,然后把匹配的结果返回

正则匹配

匹配模式
#一对一的匹配
# 'hello'.replace(old,new)
# 'hello'.find('pattern')

#正则匹配
import re
#w与W
print(re.findall('w','hello egon 123')) #['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']
print(re.findall('W','hello egon 123')) #[' ', ' ']

#s与S
print(re.findall('s','hello  egon  123')) #[' ', ' ', ' ', ' ']
print(re.findall('S','hello  egon  123')) #['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']

#
 	都是空,都可以被s匹配
print(re.findall('s','hello 
 egon 	 123')) #[' ', '
', ' ', ' ', '	', ' ']

#
print(re.findall(r'
','hello egon 
123')) #['
']
print(re.findall(r'	','hello egon	123')) #['
']

#d与D
print(re.findall('d','hello egon 123')) #['1', '2', '3']
print(re.findall('D','hello egon 123')) #['h', 'e', 'l', 'l', 'o', ' ', 'e', 'g', 'o', 'n', ' ']

#A与
print(re.findall('Ahe','hello egon 123')) #['he'],A==>^
print(re.findall('123','hello egon 123')) #['he'],==>$

#^与$
print(re.findall('^h','hello egon 123')) #['h']
print(re.findall('3$','hello egon 123')) #['3']

# 重复匹配:| . | * | ? | .* | .*? | + | {n,m} |
#.
print(re.findall('a.b','a1b')) #['a1b']
print(re.findall('a.b','a1b a*b a b aaab')) #['a1b', 'a*b', 'a b', 'aab']
print(re.findall('a.b','a
b')) #[]
print(re.findall('a.b','a
b',re.S)) #['a
b']
print(re.findall('a.b','a
b',re.DOTALL)) #['a
b']同上一条意思一样

#*
print(re.findall('ab*','bbbbbbb')) #[]
print(re.findall('ab*','a')) #['a']
print(re.findall('ab*','abbbb')) #['abbbb']

#?
print(re.findall('ab?','a')) #['a']
print(re.findall('ab?','abbb')) #['ab']
#匹配所有包含小数在内的数字
print(re.findall('d+.?d*',"asdfasdf123as1.13dfa12adsf1asdf3")) #['123', '1.13', '12', '1', '3']

#.*默认为贪婪匹配
print(re.findall('a.*b','a1b22222222b')) #['a1b22222222b']

#.*?为非贪婪匹配:推荐使用
print(re.findall('a.*?b','a1b22222222b')) #['a1b']

#+
print(re.findall('ab+','a')) #[]
print(re.findall('ab+','abbb')) #['abbb']

#{n,m}
print(re.findall('ab{2}','abbb')) #['abb']
print(re.findall('ab{2,4}','abbb')) #['abb']
print(re.findall('ab{1,}','abbb')) #'ab{1,}' ===> 'ab+'
print(re.findall('ab{0,}','abbb')) #'ab{0,}' ===> 'ab*'

#[]
print(re.findall('a[1*-]b','a1b a*b a-b')) #[]内的都为普通字符了,且如果-没有被转意的话,应该放到[]的开头或结尾
print(re.findall('a[^1*-]b','a1b a*b a-b a=b')) #[]内的^代表的意思是取反,所以结果为['a=b']
print(re.findall('a[0-9]b','a1b a*b a-b a=b')) #[]内的^代表的意思是取反,所以结果为['a=b']
print(re.findall('a[a-z]b','a1b a*b a-b a=b aeb')) #[]内的^代表的意思是取反,所以结果为['a=b']
print(re.findall('a[a-zA-Z]b','a1b a*b a-b a=b aeb aEb')) #[]内的^代表的意思是取反,所以结果为['a=b']

## print(re.findall('a\c','ac')) #对于正则来说a\c确实可以匹配到ac,但是在python解释器读取a\c时,会发生转义,然后交给re去执行,所以抛出异常
print(re.findall(r'a\c','ac')) #r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义
print(re.findall('a\\c','ac')) #同上面的意思一样,和上面的结果一样都是['a\c']

#():分组
print(re.findall('ab+','ababab123')) #['ab', 'ab', 'ab']
print(re.findall('(ab)+123','ababab123')) #['ab'],匹配到末尾的ab123中的ab
print(re.findall('(?:ab)+123','ababab123')) #findall的结果不是匹配的全部内容,而是组内的内容,?:可以让结果为匹配的全部内容
print(re.findall('href="(.*?)"','<a href="http://www.baidu.com">点击</a>'))#['http://www.baidu.com']
print(re.findall('href="(?:.*?)"','<a href="http://www.baidu.com">点击</a>'))#['href="http://www.baidu.com"']

#|
print(re.findall('compan(?:y|ies)','Too many companies have gone bankrupt, and the next one is my company'))
View Code

re模块

import re

ret = re.findall('a', 'eva egon yuan')  # 返回所有满足匹配条件的结果,放在列表里
print(ret) #结果 : ['a', 'a']

ret = re.search('a', 'eva egon yuan').group()
print(ret) #结果 : 'a'
# 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
# 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。

ret = re.match('a', 'abc').group()  # 同search,不过尽在字符串开始处进行匹配
print(ret)
#结果 : 'a'

ret = re.split('[ab]', 'abcd')  # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
print(ret)  # ['', '', 'cd']

ret = re.sub('d', 'H', 'eva3egon4yuan4', 1)#将数字替换成'H',参数1表示只替换1个
print(ret) #evaHegon4yuan4

ret = re.subn('d', 'H', 'eva3egon4yuan4')#将数字替换成'H',返回元组(替换的结果,替换了多少次)
print(ret)

obj = re.compile('d{3}')  #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串
print(ret.group())  #结果 : 123

import re
ret = re.finditer('d', 'ds3sy4784a')   #finditer返回一个存放匹配结果的迭代器
print(ret)  # <callable_iterator object at 0x10195f940>
print(next(ret).group())  #查看第一个结果
print(next(ret).group())  #查看第二个结果
print([i.group() for i in ret])  #查看剩余的左右结果
View Code

findall

res = re.findall('[a-z]+','eva egon jason')
# findall('正则表达式','带匹配的字符串')
print(res)
找出字符串中符合正则表达式全部内容 并且返回的是一个列表,列表中的元素就是正则匹配到的结果
View Code

search

res = re.search('a','eva egon jason')
print(res)  # search不会给你直接返回匹配到的结果 而是给你返回一个对象
print(res.group())  # 必须调用group才能看到匹配到的结果
函数会在字符串内查找模式匹配,直到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None,并且需要注意的是如果ret是None,再调用.group()会直接报错。这一易错点可以通过if判断来进行筛选
错误不报错
res1 = re.search('a','eva egon jason')
# search('正则表达式','带匹配的字符串')
if res1:
    print(res1.group())
View Code
注意:
    1.search只会依据正则查一次 只要查到了结果 就不会再往后查找
    2.当查找的结果不存在的情况下 调用group直接报错

match

res = re.match('a','eva egon jason')
print(res)
print(res.group())
View Code
注意:
    1.match只会匹配字符串的开头部分
    2.当字符串的开头不符合匹配规则的情况下 返回的也是None 调用group也会报错
    (match是从头开始匹配,如果正则规则从头开始可以匹配上,就返回一个对象,需要用group才能显示,如果没匹配上就返回None,调用group()就会报错)

split

ret = re.split('[ab]', 'abcd')  # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
print(ret)  # ['', '', 'cd'] 返回的还是列表

sub

ret = re.sub('d', 'H', 'eva3egon4yuan4',1)  # 将数字替换成'H',参数1表示只替换1个
# sub('正则表达式','新的内容','待替换的字符串',n)
# """
# 先按照正则表达式查找所有符合该表达式的内容 统一替换成'新的内容'  还可以通过n来控制替换的个数
# """
print(ret)  # evaHegon4yuan4
View Code

subn

ret = re.subn('d', 'H', 'eva3egon4yuan4')  # 将数字替换成'H',返回元组(替换的结果,替换了多少次)
ret1 = re.subn('d', 'H', 'eva3egon4yuan4',1)  # 将数字替换成'H',返回元组(替换的结果,替换了多少次)
print(ret)  # 返回的是一个元组 元组的第二个元素代表的是替换的个数
View Code

compile

obj = re.compile('d{3}')  #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串
res1 = obj.findall('347982734729349827384')
print(ret.group())  #结果 : 123
print(res1)  #结果 : ['347', '982', '734', '729', '349', '827', '384']
View Code

finditer

import re
ret = re.finditer('d', 'ds3sy4784a')   #finditer返回一个存放匹配结果的迭代器
print(ret)  # <callable_iterator object at 0x10195f940>
print(next(ret).group())  # 等价于ret.__next__()
print(next(ret).group())  # 等价于ret.__next__()
print(next(ret).group())  # 等价于ret.__next__()
print(next(ret).group())  # 等价于ret.__next__()
print(next(ret).group())  # 等价于ret.__next__()
print(next(ret).group())  # 等价于ret.__next__()   超出迭代取值的范围 直接报错
print(next(ret).group())  #查看第一个结果
print(next(ret).group())  #查看第二个结果
print([i.group() for i in ret])  #查看剩余的左右结果
View Code

起别名

import re
res = re.search('^[1-9](d{14})(d{2}[0-9x])?$','110105199812067023')
还可以给某一个正则表达式起别名
res = re.search('^[1-9](?P<password>d{14})(?P<username>d{2}[0-9x])?$','110105199812067023')
print(res.group())
print(res.group('password'))
print(res.group(1))
print(res.group('username'))
print(res.group(2))
print(res.group(2))
print(res.group(1))
View Code

findall

ret1 = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
ret2 = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')  # 忽略分组优先的机制
print(ret1,ret2)  # ['oldboy']     这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
View Code

split

ret=re.split("d+","eva3egon4yuan")
print(ret) #结果 : ['eva', 'egon', 'yuan']

ret1=re.split("(d+)","eva3egon4yuan")
print(ret1) #结果 : ['eva', '3', 'egon', '4', 'yuan']
View Code

 

原文地址:https://www.cnblogs.com/komorebi/p/11203469.html