正则表达式

1.1正则表达式

正则表达式和字符串

在编程里字符串是涉及到最多的一种数据结构,对字符串操作的需要几乎无处不在。

比如判断一个字符串是否合法的email地址,虽然可以提取@前面和后面的子串,又再分别判断是否是单词和域名,但这样很麻烦,而且代码难以复用。

 

正则表达式式一种用来模糊匹配字符串的方法,它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配了”,否则该“没有匹配到该字符串”

需要导入正则的模块

import re

字符匹配(普通字符,元字符)

1.普通字符:数字字符和英文字母和自身匹配

2.元字符:.  ^  $  *  + ?  {}  [] () |  \

re.方法("规则","匹配的字符串")

.  匹配任意一个字符,除了\n换行符

1 #findall查找所有字符
2 print(re.findall("a.","ssdfyildazvdfeewrae"))  #['az', 'ae']  匹配a后面的任意一个字符
3 print(re.findall("a..","ssdfyildazvdfeewrae"))  #['azv']    匹配a后面的任意两个个字符
.方法

^  匹配以什么开头的字符

1 re_str = "ssdfyildazvdfeewrae"
2 print(re.findall("^s..",re_str))  # ['ssd']  #匹配以s开头后面两个任意字符
3 print(re.findall("^aa",re_str)) #[]  #匹配aa开头
^方法

$  匹配以什么结尾

1 re_str = "ssdfyildaaazvdfeewrae"
2 print(re.findall("ee$",re_str))  #[]
3 print(re.findall("ae$",re_str))  #['ae']
$方法

*  字符*   匹配前面的字符 出现的0-无穷次

 1 import re
 2 
 3 re_str = "ssdfyilddddkaaazvdfeewrae"
 4 
 5 # print(re.findall("*",re_str)) #报错,要加匹配字符
 6 print(re.findall("d*",re_str))#匹配d出现的0到无穷次 没有,也匹配上了
 7 # ['', '', 'd', '', '', '', '', 'dddd', '', '', '', '', '', '', 'd', '', '', '', '', '', '', '', '']
 8 print(re.findall("ld*k",re_str)) #['lddddk']   #匹配ld*k  匹配*前面的d字符出现的0到无穷次
 9 
10 print(re.findall("sd*",re_str)) #['s', 'sd']   匹配sd*  d出现的0到无穷次
11 print(re.findall("ras*",re_str)) #['ra']    匹配ras*  res中s出现的0到无穷次
*方法

+  字符+  匹配前面的一个字符出现的1-无穷次 ,最少有1次

1 re_str = "ssdfyilddddkaaazvddfeewrae"
2 
3 print(re.findall("dd+",re_str)) #['dddd']  匹配dd+中d出现的一到无穷次
4 print(re.findall("d+",re_str))  #['d', 'dddd', 'dd']  匹配d+中d出现的一到无穷次
+ 用法

?  字符?  匹配前面字符重复零次或一次

1 name = "asdfqwzerzxcv"
2 print(re.findall("x?",name)) #匹配x字符出现的0次或者1次
3 # ['', '', '', '', '', '', '', '', '', 'x', '', '', '']
4 print(re.findall("zx?",name))  #['z', 'zx']  #匹配zx  x出现的0次或者1次
?用法 

注:* + ?等都是贪婪匹配,也就是尽最大能力去匹配,匹配字符后面加?变成了惰性匹配,一般都是用贪婪匹配

1 name = "asdfqwzerzxcv"
2 print(re.findall("zx*?",name))  #['z', 'z'] #惰性匹配,最小匹配原则
惰性匹配

{}  字符{n} 匹配字符出现的n次,字符{1,n}匹配字符出现1到n次

1 name = "aasdfqwzerzxcvaaaavv"
2 print(re.findall("aa{1,5}",name)) #['aa', 'aaaa']  #匹配aa a出现的一到5次之间
3 print(re.findall("aa{1,5}v",name)) #['aaaav']   #匹配aa{1,5}v  ,a出现的一到5次之间
4 print(re.findall("a{5}",name))  #[] 只匹配a出现的5次
5 print(re.findall("a{3}",name))  #['aaa'] 只匹配a出现的3次
{}方法

 

[]  字符[字符集]  匹配字符集中的某一个符号

1 name = "aasdfqawzerzxcvaaaavv"
2 print(re.findall("a[a]",name))  #['aa', 'aa', 'aa'] #只匹配aa
3 print(re.findall("a[a]a",name))  #['aaa'] #只匹配aaa
4 print(re.findall("f[.q]",name)) #['fq']#匹配f.或者fq
5 print(re.findall("f[.q]b",name)) ##匹配[] f.b或者fqb
[]方法

[字符集]  里面的字符集都是普通字符,除了-,^.\

- ^ \这三个符号在字符集有特殊功能的符号,其它都是普通字符

 1 [] 字符集中- 的方法    -  组成一个连接范围的数字
 2 name = "aasdfqawzerzxcvaaaavv"
 3 print(re.findall("a[a-z]",name))#['aa', 'aw', 'aa', 'aa']    #匹配a[a到z]的任意字符
 4 alp_num = "a12a 34a5567asdfqwer"
 5 print(re.findall("a[0-9 a-z]",alp_num)) #['a1', 'a ', 'a5', 'as']#空格也是普通字符
 6 print(re.findall("a[0-9a-zA-Z]",alp_num)) #['a1', 'a5', 'as']  
 7 
 8 
 9 []字符集中^的方法    ^非,把相反的给找出来
10 name = "aasdfqawzerzxcvaaaavv"
11 tes = "abc"
12 print(re.findall("[^0-9]",tes)) #['a', 'b', 'c']    #把非0到9数字给匹配出来
13 print(re.findall("a[^0-9]",name))#['aa', 'aw', 'aa', 'aa']  把匹配a字符集中非0到9数字给匹配出来
14 
15 
16 []字符集中\的方法,把普通的特殊字符变得有意义
17 aa = "advca11234"
18 print(re.findall("[\d]",aa))    #['1', '1', '2', '3', '4'] #\是转义字符,把普通字符,实现特殊的功能
[-] [^] [\]的方法

 

\  元字符的转义符\

反斜杠后面跟元字符去除特殊功能,比如\.  \*

反斜杠后边跟普通字符实现特殊功能比如\d

\d  匹配任何十进制数;它相当于类 [0-9]。
\D 匹配任何非数字字符;它相当于类 [^0-9]。
\s  匹配任何空白字符;它相当于类 [ \t\n\r\f\v]。
\S 匹配任何非空白字符;它相当于类 [^ \t\n\r\f\v]。
\w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
\W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]
\b  匹配一个特殊字符边界,比如空格 ,&,#等

1 bb = "axs1233_sa _%"
2 print(re.findall("\d",bb)) #['1', '2', '3', '3']
3 print(re.findall("\D",bb)) #['a', 'x', 's', '_', 's', 'a', ' ', '_', '%']
4 print(re.findall("\s",bb)) #[' ']
5 print(re.findall("\S",bb)) #['a', 'x', 's', '1', '2', '3', '3', '_', 's', 'a', '_', '%']
6 print(re.findall("\w",bb))#['a', 'x', 's', '1', '2', '3', '3', '_', 's', 'a', '_']
特殊字符的转义
1 cal = "()(_)(*)(s)12+(28*10+5+2-8-3*(2-1))"
2 print(re.findall("\(\)",cal)) #['()'] #只匹配普通字符的括号()
3 print(re.findall("\([\w]\)",cal)) #['(_)', '(s)'] #匹配(任意一个字母数字_)
简单的转义

 

1 gan = "\\"
2 print(gan)#\  python解释器中字符串\\,才表示一个\
3 print(re.findall("\\\\",gan)) #['\\'],其实就是一个\

 

r"字符串"  表示原始字符串(r---> raw string)

|  字符a|字符b    匹配字符a或者字符b 的表示或得方法 

1 ss = "abs,youbyy"
2 print(re.findall("a|b",ss))#['a', 'b', 'b']
3 print(re.findall("ou|y",ss)) #['y', 'ou', 'y', 'y']
| 或方法

()  (字符)优先匹配字符里面的内容。

1 tot = "asdasdasdasd"
2 print(re.findall("(asd)*",tot)) #['asd', ''] #0到无穷匹配
3 print(re.findall("(asd)?",tot)) #['asd', 'asd', 'asd', 'asd', ''] #0到1次匹配asd
4 print(re.findall("(asd)+",tot))  #['asd'] #1到无穷匹配
5 print(re.findall("(asd)",tot))   #['asd', 'asd', 'asd', 'asd']
() 的方法

 

 

re模块的常用方法

1.re.findall()

1 import re
2 print(re.findall("a",bb)) #返回所有满足匹配条件的结果,放在列表里

2.re.match()

语法

re.match(pattern, string, flags=0)

 

pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

匹配成功re.match方法返回一个匹配位置的对象,否则返回None。(从最开始匹配) 

我们可以使用group(num)或groups()匹配对象函数来获取匹配表达式。 

group(num=0) 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
groups() 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
 1 bb = "advca11234"
 2 print(re.match("12",bb))  #None  不是开始位置匹配
 3 print(re.match("adv",bb)) #开始位置匹配,返回匹配的位置对象
 4 #<_sre.SRE_Match object; span=(0, 3), match='adv'>
 5 
 6 print(re.match("adv",bb).span()) #(0, 3) 获取匹配对象的位置
 7 #
 8 print(re.match("adv",bb).group()) # adv  #获取匹配对象的结果内容
 9 print(re.match("adv",bb).groups()) #() #获取模型中匹配到的分组结果
10 print(re.match("adv",bb).groupdict()) #{}  #获取模型中匹配到的分组结果 {}
match

 

3re.search方法

re.search扫描整个字符串并返回第一成功的匹配

用法:re.search(pattern, string, flags=0)

匹配成功re.search方法返回一个匹配的对象,否则返回None

我们可以使用group(num)或groups()匹配对象函数来获取匹配表达式

 1 bb = "advca11234"
 2 print(re.search("\d+",bb))
 3 #返回一个函数匹配对象  span 是匹配的位置   math是匹配对象的内容
 4 #<_sre.SRE_Match object; span=(5, 10), match='11234'>
 5 
 6 info = "yj18yj18yj19"
 7 print(re.search("(?P<name>[a-z]+)",info).group("name")) #yj  #得到特定的分组信息内容
 8 print(re.search("(?P<name>[a-z]+)(?P<age>\d+)",info).group("name","age"))#('yj', '18') #得到特定的分组信息 ,以元祖返回
 9 print(re.search("(?P<name>[a-z]+)(?P<age>\d+)",info).group())# yj18 #获取分组信息的所有内容、
10 print(re.search("(?P<name>[a-z]+)(?P<age>\d+)",info).groups()) #('yj', '18')
11 #得到分组的所有信息,以元祖返回
12 print(re.search("(?P<name>[a-z]+)(?P<age>\d+)",info).groupdict())# yj18 #获取分组的所有内容、
13 #{'name': 'yj', 'age': '18'} 以字典返回,分组信息
14 print(re.search("(?P<name>[a-z]+)(?P<age>\d+)",info)) #得到是分组的对象
15 
16 #?P<name> 给信息做一个分组
search方法

 

re.match与re.search的区别

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;

而re.search匹配整个字符串,直到找到一个匹配。

 

4re.sub()   用于替换字符串中的匹配项。

语法:re.sub(pattern, repl, string, count=0)

  • pattern : 正则中的模式字符串。
  • repl : 替换的字符串,也可为一个函数。
  • string : 要被查找替换的原始字符串。
  • count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
1 phone = "110-119-911-112"
2 print(re.sub(r"-"," ",phone,count=2))#检索字符串的-,把前两个替换成空格
3 #110 119 911-112
re.sub方法

5re.split() 分割字符串

语法:split(pattern, string, maxsplit=0, flags=0):

maxsplit : 模式匹配后分割的最大次数,默认 0 表示替换所有的匹配。

1 alp = "a b c  d"
2 print(re.split("\s+",alp,maxsplit=2)) 
3 #['a', 'b', 'c  d'] #分割前两个的字符串个空格,以列表形式返回
re.split方法

6re.finditer() 方法,把找到的结果做成一个迭代器对象,取值用next()

语法和findall一样

1 phone = "110-119-911-112"
2 print(re.finditer("\d+",phone))#<callable_iterator object at 0x0000009E83BCAE10>
3 te = re.finditer("\d+",phone)
4 print(next(te).group()) #110
5 print(next(te).group()) #119
6 print(next(te).group()) #911
re.finditer方法

 

字符类

[0-9] 匹配任何数字。类似于 [0123456789]
[a-z] 匹配任何小写字母
[A-Z] 匹配任何大写字母
[a-zA-Z0-9] 匹配任何字母及数字
[^aeiou] 除了aeiou字母以外的所有字符
[^0-9] 匹配除了数字外的字符

 

 特殊转义字符类

实例描述
. 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。
\d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个非数字字符。等价于 [^0-9]。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
\W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。
posted @ 2016-12-15 10:07  keme  阅读(463)  评论(0编辑  收藏  举报