Regular Expression。缩写regex,regexp,R等:
正则表达式是文本处理极为重要的工具。用它可以对字符串按照某种规则进行检索,替换。
Shell编程和高级编程语言中都支持正则表达式。
BRE:基本正则表达式,grep、sed、vi等软件支持,vim有扩展。
ERE:扩展正则表达式,egrep(grep-E)、sed-r。
PCRE: re模块。Python中。几乎所有高级语言都是PCRE的方言或者变种。
代码
说明
举例
.
匹配除换行符外任意一个字符
.
[abc]
字符集合,只能表示一个字符位置。匹配所包含的任意一个字符
[abc]匹配plain中的’a’
[^abc]
字符集合,只能表示一个字符位置,匹配除去集合内字符的任意一个字符。
[^abc]可以匹配plain中’p’,’l’,’i’或者’n’
[a-z]
字符范围,也是个集合,表示一个字符位置,匹配所包含的任意一个字符。
[a-d]可以匹配plain中的’a’
[^a-z]
字符范围,也是个集合,表示一个字符位置,匹配除去集合内字符的任意一个字符。
[a-d]可以匹配plain的中’p’,’l’,’i’或者’n’
\b
匹配单词的边界
\ba在文本中找到单词a开头的,a\b找到以a结尾的。
\B
不匹配单词的边界
t\B包含t的单词但是不以t结尾,write
\Bb不以b开头但是包含b的单词,able
\d
[0-9]匹配1位数字
\d
\D
[^0-9]匹配一位非数字
\w
匹配[a-zA-Z0-9],包括中文的字
\w
\W
匹配\w之外的字符。
\s
匹配1位空白字符,包括换行符,制表符、空格[\f\r\n\t\v]
\S
匹配非空白字符。
凡是在正则表达式中有特殊意义的符号,如果想使用它他的本意,使用\转义,反斜杠自身,得使用\\ \r 转义后代表回车 \n 换行
代码
说明
举例
*
表示前面的正则表达式会重复0次或者多次
e\w*单词e中可以有非空白字符。
+
表示前面的正则表达式重复至少1次
e\w+单词e后面至少有一个非空白字符。
?
表示前面的正则表达式会重复0次或者1次
e\w?单词e后面至多有一个非空白字符。
{n}
重复固定的n次
e \w{1}单词中e后面只能有一个非白字符。
{n,}
重复至少n次
e \w{1,} >>>e\w+
e\w{0,}>>>e\w*
e \w{0,1}>>>e\w?
{n,m}
重复n到m次
e \w{1,10}单词后面至少一个,至多10个非空白字符。
(1)匹配手机号码:
\d{11,}
(2)匹配中国座机:
\d{3,4}-\d{7,8}
代码
说明
举例
x | y
匹配x或者y
Wood took foot food
使用w|food 或者(w|f)odd
捕获
(pattern)
使用小括号指定一个字表达式,也叫分组捕获后会自动分配组号从1开始,可以改变优先级
\数字
匹配对应的分组
(very)\1匹配very very,但捕获的组group是very。
(?:pattern)
如果仅仅为了改变优先级,就不需要捕获分组
(?:w|f)ood ‘industr(?:y|lies)’等价于’industry|industries’
(?
分组捕获,但是可以通过name访问分组。Python的语法必须是(?P
零宽断言
(?=exp)
零宽度正测先行断言:
断言exp一定在匹配的右边出现,也就是说断言后面一定跟个exp
f(?=00)f后面一定有oo出现
(?<=exp)
零宽度正回顾后发断言:
断言exp一定出现在匹配的左边出现。也就是说前面一定有个exp前缀
(?<=f)ood,(?<=t)ook分别匹配ood,ook,ook前面一定有t出现。
负向零宽断言
(?!exp)
零宽度负预测先行断言;
断言一定不会出现在右侧,也就是说断言后面一定不是exp
\d{3}(?!\d)匹配三位数字,断言三位数字后面一定不能是数字
(?<!exp)
零宽度负回顾后发断言
断言exp一定不能出现在左侧,也就是说断言前面一定不能是exp
(?<!f)ood ood 的左边一定不是f
注释
(?#comment)
注释
断言不占分组号,断言如同条件,只是要求匹配必须满足断言条件。
分组和捕获是同一个意思;
使用正则表达式时候,能用简单表达式,就不要复杂的表达式。
代码
说明
举例
*?
匹配任意次,但是尽可能少重复
*?尽可能的少,可以是没有。
+?
匹配至少1次,但是尽可能少重复
+?至少一次。
??
匹配0次或者1次,尽可能少重复
??尽可能的少,至少0次。
{n,}?
匹配至少n次,尽可能没有
{n,m}
至少匹配n次,至多m次,尽可能少重复
Very very very happy
V.*y 和v.*?y
7)引擎选项:
代码
说明
Python中
ignoreCase
匹配时忽略大小写
re.l re.lGNORECASE
Singleline
单行模式,可以匹配所有字符,包括\n
re.S re.DOTALL
Multine
多行模式^,行首,$行尾
re.M re.MULTLINE
lgnorePatternWhites
忽略表达式中的空白字符,如果要使用空白字符转义,#可以用来做注释
re.x
re.VERBOSE
单行模式;
.可以匹配所有字符,包括换行符
^表示整个字符串的开头,$整个字符串的结尾。
多行模式:
.可以匹配除了换行符之外的字符。
^表示整个字符串的开头,$整个字符串的结尾。
^表示整个字符串的开始,$表示整个字符串的结尾。开始指的是\n紧接着下一个字符,结束指的是/n前的字符。
可以认为,单行模式就如同看穿了换行符,所有文本就是一个长长的只有一行的字符串,所有^表示整个字符串的开头,$整个字符串的结尾。
多行模式,注意字符串看不见的换行符,\r\n 会影响e$测试,e$只能匹配e\n.
*重复任意次 限制的话用*? 得到了限制。
默认是贪婪模式,也就是尽量多匹配长的字符串。
匹配一个0-9999之间的任意数字:
^([1-9]?\d\d?|\d)(?!\d)
匹配合法的ip地址:
(\d{1,3}\.){3}\d{1,3}
192.168.1.150
0.0.0.0
255.255.255.255
17.16.52.100
172.16.0.100
400.400.999.888
001.022.003.000
257.257.255.256
ip的验证采用python 的socket模块.
选出含有ftp的链接。且文件的类型是gz或者xz的。
.*ftp.*/([^/]*\.(?:gz|xz))
1)常量:r.M(re.MULTILINE)多行 r.S(re.DOTALL)单行。 r.L(re.IGNORECASE)忽略大小写。 r.X(re.VERBOSE)忽略空白字符。 使用|或运算
2)方法、编译:
re.compile(pattern,flags=0)
设定flag,编译模式。返回正则表达式对象regex。
Pattern就是正则表达式的字符串,flags是选项,正则表达式需要被编译,为了提高效率,为了提高效率,这些编译后的结果就会被保存,下次使用同样的pattern的时候,就会不需要再次编译。
re的其他方法为了提高效率都调用了编译方法,就是为了提速。
3)Re.matth(pattern,string,flags=0)匹配只是做了单次的匹配。从头开始,从第一个字符串匹配上。对匹配字符串加上了一^字符。只是匹配了一次。
Regex.match编译后可以调整位置(切片)可以设置开始和结束的位置。返回match对象 regex = re.compile
match必须是以他开头的,指定索引。
4)re.search(pattern,string,flags=0) 全文搜索,不限定在哪里开始查找,找到第一个匹配对象立即返回,找不到返回none。只是找第一个。
Regex.search()可以指定位置。
5)re.fullmatch(pattern,string,flags=0)完全匹配。
regex.fullmatch(string) 整个字符串和正则表达式匹配。
import re
s = '''bottle\nbag\nbig\napple'''
for i,c in enumerate(s,1):
print((i-1,c),end='\n' if i%8==0 else ' ')
print()
print('--match--')
result = re.match('b',s)
print(1,result)
result= re.match('a',s)
print(2,result)
result = re.match('^a',s,re.M)
print(3,result)
result = re.match('^a',s,re.S)
print(4,result)
regex = re.compile('a')
result =regex.match(s)
print(5,result)
result=regex.match(s,15)
print(6,result)
print('--search--')
result = re.search('a',s)
print(7,result)
regex = re.compile('b')
result=regex.search(s,1)
print(8,result)
regex=re.compile('^b',re.M)
result=regex.search(s)
print(8.5,result)
result=regex.search(s,8)
print(9,result)
print('--fullmatch--')
result=re.fullmatch('bag',s)
print(10,result)
regex=re.compile('bag')
result=regex.fullmatch(s)
print(11,result)
result = regex.fullmatch(s,7)
print(12,result)
result=regex.fullmatch(s,7)
print(13,result)
(0, 'b') (1, 'o') (2, 't') (3, 't') (4, 'l') (5, 'e') (6, '\n') (7, 'b')
(8, 'a') (9, 'g') (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a')
(16, 'p') (17, 'p') (18, 'l') (19, 'e')
--match--
1 <_sre.SRE_Match object; span=(0, 1), match='b'>
2 None
3 None
4 None
5 None
6 <_sre.SRE_Match object; span=(15, 16), match='a'>
--search--
7 <_sre.SRE_Match object; span=(8, 9), match='a'>
8 <_sre.SRE_Match object; span=(7, 8), match='b'>
8.5 <_sre.SRE_Match object; span=(0, 1), match='b'>
9 <_sre.SRE_Match object; span=(11, 12), match='b'>
--fullmatch--
10 None
11 None
12 None
13 None
6)、全文搜索;
Re.findall(pattern,string,flags=0)全文搜索,全部搜索。 返回匹配项的列表
Regex.findall(string,)
Re.finditer() 返回匹配项的可迭代对象。返回的都是match对象
Regex.finditer()
import re
s = '''bottle\nbag\nbig\napple'''
for i,c in enumerate(s,1):
print((i-1,c),end='\n' if i%8==0 else ' ')
print()
print('--findall--')
result = re.findall('b',s)
print(1,result)
regex = re.compile('^b')
result = regex.findall(s)
print(2,result)
regex=re.compile('^b',re.M)
result=regex.findall(s,7)
print(3,result)
regex=re.compile('^b',re.S)
result=regex.findall(s)
print(4,result)
regex=re.compile('^b',re.M)
result=regex.findall(s,7,10)
print(5,result)
print('--finder--')
result=regex.finditer(s)
print(1,type(result))
print(2,next(result))
print(3,next(result))
(0, 'b') (1, 'o') (2, 't') (3, 't') (4, 'l') (5, 'e') (6, '\n') (7, 'b')
(8, 'a') (9, 'g') (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a')
(16, 'p') (17, 'p') (18, 'l') (19, 'e')
--findall--
1 ['b', 'b', 'b']
2 ['b']
3 ['b', 'b']
4 ['b']
5 ['b']
--finder--
1
2 <_sre.SRE_Match object; span=(0, 1), match='b'>
3 <_sre.SRE_Match object; span=(7, 8), match='b'>
re.sub(pattern,repleacement,string,count=0,flags=0) 替换
regex.sub(replacement,string,count=0) 替换
使用pattern对字符串string进行匹配,对匹配项使用replancement替换吧,可以是string,bytes,function。
re.subn(pattern,replacement,string,count=0,flags=0)输出二元组,提供替换的次数。
regex.subn(replacement,string,count=0,flags=0)
regex = re.compile('b\wg')
result = regex.sub('magedu',s)
print(1,result)
result = regex.sub('magedu',s,1)
print((2,result))
regex =re.compile('\s+')
result = regex.subn('\t',s)
print(3,result)
1 bottle
magedu
magedu
apple
(2, 'bottle\nmagedu\nbig\napple')
3 ('bottle\tbag\tbig\tapple', 3)
Re.split(pattern,string,maxsplit=0,flag=0)
Re.split分隔字符串
import re
s= '''01 bottle
02 bag
03 big1
100 able'''
x = re.split('\s+\d+\s+',' '+s)
print(x)
['', 'bottle', 'bag', 'big1', 'able']
使用小括号的pattern捕获的数据放到了组group中。
Match,search函数均可以返回match对象。Findall返回的是字符串列表。。Finditer一个个返回match对象。。
如果pattern中使用了分组,如果有匹配结果,会在match对象中。
1)使用group(N)方式返回对应的分组,1-N对应的是分组,0返回整个匹配的字符串。
2)如果使用了命名分组,可以使用group(‘name’)的方式取分组。
3)也可以使用groups()返回所有组。
4)使用groupdict返回所有命名的分组。
Matcher.group()
matcher.groups()返回的是二元组。
Matcher.groupdict()字典。
import re
s = '''bottle\nbag\nbig\napple'''
for i,c in enumerate(s,1):
print((i-1,c),end='\n' if i%8==0 else ' ')
print()
regex = re.compile('(b\w+)')
result = regex.match(s)
print(type(result))
print(1,'match',result.groups())
result =regex.search(s,1)
print(2,'search',result.groups())
regex = re.compile('(b\w+)\n(?P
result = regex.match(s)
print(3,'match',result)
print(4,result.group(3),result.group(2),result.group(1))
print(5,result.group(0).encode())
print(6,result.group('name2'),result.group('name3'))
print(6,result.groups())
print(7,result.groupdict())
result = regex.findall(s)
for x in result:
print(8,type(x),x)
regex = re.compile('(?P
b\w+)')result = regex.finditer(s)
for x in result:
print(9,type(x),x,x.group(),x.group('head'))
(0, 'b') (1, 'o') (2, 't') (3, 't') (4, 'l') (5, 'e') (6, '\n') (7, 'b')
(8, 'a') (9, 'g') (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a')
(16, 'p') (17, 'p') (18, 'l') (19, 'e')
1 match ('bottle',)
2 search ('bag',)
3 match <_sre.SRE_Match object; span=(0, 14), match='bottle\nbag\nbig'>
4 big bag bottle
5 b'bottle\nbag\nbig'
6 bag big
6 ('bottle', 'bag', 'big')
7 {'name2': 'bag', 'name3': 'big'}
8
9
9
9
1)判断邮箱地址。
\w+[-.\w]*@[\w-]+(\.[\w-]+)+
2)html提取:
<[^<>]+>(.*)<^<>+>
3)URL提取。
(\w+)://([^\s]+)
4)身份验证
身份证验证需要使用计算公式,最严格的应该是实名验证。
\d{17}[0-9xX]|\d{15}
5)单词统计利用makekey等进行查找。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章