一、正则表达式概念
Ÿ 使用单个字符串来描述匹配一系列符合某个句法规则的字符串
Ÿ 是对字符串操作的一种逻辑公式
Ÿ 应用场景:处理文本和数据
Ÿ 正则表达式过程:依次拿出表达式和文本中的字符比较,如果每一个字符都能匹配,则匹配成功;否则匹配失败
为什么使用正则?
把匹配做成一个规则
‘a’<=b<=’z’
二、Python正则表达式re模块
#EXAMPLE
# -*- coding: utf-8 -*- import re #字符串匹配 str='hello demo' print str.find('demo') #返回起始索引 print '-------' #第一个正则表达式demo pa=re.compile(r'hello')#返回pattern实例 ,最好使用源字符串 print type(pa) ma=pa.match(str) #该方法返回一个match对象或者none print ma.group() #返回str or tuple,内容上,返回的是源字符串中的匹配出来的字符串 print ma.span() #返回匹配字符串在源字符串中的位置(起始,不包含末尾) print ma.string #返回源字符串 print ma.re #返回pattern实例 print '-------' #忽略大小写的正则表达式 pa=re.compile(r'imooc',re.IGNORECASE)#返回pattern实例 ma=pa.match('ImOOc python') #该法返回一个match对象或者none print ma.group() pa=re.compile(r'(imooc)',re.IGNORECASE)#返回pattern实例 ma=pa.match('ImOOc python') #该法返回一个match对象或者none #以上两句等价于 #ma=re.match(r'(imooc)','ImOOc python') #格式:re.match(pattern,string ) 但是Pattern只能用一次 print ma.groups() #返回元组 print ma.group() #返回字符串
三、正则表达式语法
对于单个字符的匹配
字符 | 匹配 |
. | 匹配任意字符(除了\n) |
[…] | 匹配字符集 |
\d/\D | 匹配数字/非数字 |
\s/\S | 匹配空白/非空白字符 |
\w/\W | 匹配单词字符[a-zA-Z0-9]/非单词字符 |
字符集例子: [abc],[a-z](a到z的所有字符),[a-zA-Z0-9],
如果想匹配有中括号的字符串,需要对中括号进行转译(转外层的中括号)
对于多个个字符的匹配
字符 | 匹配 |
* | 匹配前一个字符0次或者无限次 |
+ | 匹配前一个字符1次或者无限次 |
? | 匹配前一个字符0次或者1次 |
{m}/{m,n} | 匹配前一个字符m次或者n次 |
*?/+?/?? | 匹配模式变为非贪婪(尽可能少匹配字符) |
e.g.
匹配以大写字母开头的:
ma=re.match(r'[A-Z][a-z]*','Aaaa') print ma.group()
ma=re.match(r'[A-Z][a-z]*','Aaa1') print ma.group() #只匹配到Aaa
匹配以Python变量命名规则为标准的字符串:
ma=re.match(r'[_A-Za-z]+[_\w]*','_10')
匹配0-99的数字字符串:
ma=re.match(r'[1-9]?[0-9]','99') print ma.group()
匹配6-10位数字的QQ邮箱
ma=re.match(r'[\w]{6,10}@qq.com','ass123@qq.com ') print ma.group()
非贪婪模式:
# -*-coding:utf-8-*- import re ma=re.match(r'[0-9][a-z]*?','1bc') print ma.group() #最少匹配0次 1 ma=re.match(r'[0-9][a-z]+?','1bc') print ma.group() #最少匹配1次 1b ma=re.match(r'[0-9][a-z]??','1bc') print ma.group() #最少匹配0次 1
边界匹配(指定开头和结尾)
字符 | 匹配 |
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
\A/\Z | 指定的字符串必须出现在开头/结尾 |
匹配以163.com结尾的字符串:
ma=re.match(r'[\w]+@163.com$','123asd@163.com') print ma.group()
或者:
ma=re.match(r'[\w]*@163.com\Z','123asd@163.com') print ma.group()
字符 | 匹配 |
| | 匹配左右任意一个表达式 |
(ab) | 括号中表达式作为一个分组 |
\<number> | 引用编号为num的分组匹配到的字符串 |
(?P<name>) | 分组起一个别名 |
(?P=name) | 引用别名为name的分组匹配字符串 |
e.g:
匹配左右任意字符串:
ma=re.match(r'abd|c','c') print ma.group()
匹配126或者163邮箱
ma=re.match(r'[\w]{4,6}@(163|126).com','hello@126.com') print ma.group() #等价于: ma=re.match(r'[\w]{4,6}@163.com|[\w]{4,6}@126.com','hello@126.com') print ma.group()
验证XML的有效性
ma=re.match(r'<([\w]+>)\1','<book>book>') print ma.group() #<book>book> ma=re.match(r'<([\w]+>)[\w]*</\1','<book>python</book>') print ma.group() #<book>python</book>
使用别名引用分组:
ma=re.match(r'<(?P<mark>[\w]+>)[\w]*</(?P=mark)','<book>python</book>') print ma.group() #<book>python</book>
注:以别名引用分组,方便使用,引用方式:(?P=mark)
四、Python正则表达式——re模块其他方法
1. search(pattern,string,flags=0)
在一个字符串中查找匹配
e.g.
str='booknum=999'
info=re.search(r'\d+',str)
print info.group()
2. findall(pattern,string,flags=0)
找到匹配,返回所有匹配部分的列表
e.g.
str='book=10,vedio=99,songs=20'
info=re.findall(r'\d+',str)
print info
#['10', '99', '20']
sum([int(x) for x in info]) #列表解析,求列表元素之和
3. sub(pattern,repl,string,count=0,flags=0)
将字符串中匹配正则表达式的部分替换为其他值
(repl可以是字符串也可以是函数,string与pattern匹配产生match对象传给函数,接着替换返回函数的返回值那部分,其余不变)
e.g.
第一种,repl是字符串
str='literal books=1000' info=re.sub(r'\d+','1001',str) print info #literal books=1001
第二种,repl是函数
str1='literalbooks=1000'
def add1(match):
val=match.group()
num=int(val)+1
return str(num)
info=re.sub(r'\d+',add1,str1)
print info
#literal books=1001
4. split(pattern,string,maxsplit=0,flags=0)
根据匹配分割字符串,返回分割字符串组成的列表(比较灵活)
e.g.
str1='lang:pythonc c++ java,c#'
result=re.split(r':| |,',str1)
print result
#['lang', 'python', 'c', 'c++', 'java','c#']