python正则表达式
正则表达式
正则表达式是一种用来模糊匹配字符串的方法,它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配了”,否则该“没有匹配到该字符串”
在线调试工具:点击
一、常用正则表达式
- 单字符:
- . : 除换行以外所有字符
- [] :[aoe] [a-w] 匹配集合中任意一个字符
- \d :数字 [0-9]
- \D : 非数字
- \w :数字、字母、下划线、中文
- \W : 非\w
- \s :所有的空白字符包,括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
- \S : 非空白
- 数量修饰:
- * : 任意多次 >=0
- + : 至少1次 >=1
- ? : 可有可无 0次或者1次
- {m} :固定m次 hello{3,}
- {m,} :至少m次
- {m,n} :m-n次
- 边界:
- $ : 以某某结尾
- ^ : 以某某开头
- 分组:
- (ab)
- 贪婪模式: .*
- 非贪婪(惰性)模式: .*?
- re.I : 忽略大小写
- re.M :多行匹配
- re.S :单行匹配
- re.sub(正则表达式, 替换内容, 字符串)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
import re key = 'bobo@hit.edu.com' #想要匹配到hit. res = re.findall( 'h.*\.' ,key) print (res) #['hit.edu.'] res = re.findall( 'h.*?\.' ,key) print (res) #['hit.'] #匹配出i开头的行 string = '''fall in love with you i love you very much i love she i love her''' res = re.findall( '^.*' ,string,re.M) print (res) #['fall in love with you', 'i love you very much', 'i love she', 'i love her'] string1 = """<div>静夜思 窗前明月光 疑是地上霜 举头望明月 低头思故乡 </div>""" res = re.findall( '<div>(.*)</div>' ,string1,re.S) print (res) #['静夜思\n窗前明月光\n疑是地上霜\n举头望明月\n低头思故乡\n'] string1 = """<div>静夜思 窗前明月光 疑是地上霜 举头望明月 低头思故乡 </div>""" res = re.findall( '<div>(.*)</div>' ,string1) print (res) #[] |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
# =================================匹配模式================================= #一对一的匹配 # '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'] #\n \t都是空,都可以被\s匹配 print (re.findall( '\s' , 'hello \n egon \t 123' )) #[' ', '\n', ' ', ' ', '\t', ' '] #\n与\t print (re.findall(r '\n' , 'hello egon \n123' )) #['\n'] print (re.findall(r '\t' , 'hello egon\t123' )) #['\n'] #\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与\Z print (re.findall( '\Ahe' , 'hello egon 123' )) #['he'],\A==>^ print (re.findall( '123\Z' , 'hello egon 123' )) #['he'],\Z==>$ #^与$ 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\nb' )) #[] print (re.findall( 'a.b' , 'a\nb' ,re.S)) #['a\nb'] print (re.findall( 'a.b' , 'a\nb' ,re.DOTALL)) #['a\nb']同上一条意思一样 #* 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' )) #['abbb'] print (re.findall( 'ab{1,}' , 'abbb' )) #['abbb'] #'ab{1,}' ===> 'ab+' print (re.findall( 'ab{0,}' , 'abbb' )) #['abbb'] #'ab{0,}' ===> 'ab*' #[] print (re.findall( 'a[1*-]b' , 'a1b a*b a-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' )) #结果为['a1b'] print (re.findall( 'a[a-z]b' , 'a1b a*b a-b a=b aeb' )) #结果为['aeb'] print (re.findall( 'a[a-zA-Z]b' , 'a1b a*b a-b a=b aeb aEb' )) #结果为['aeb', 'aEb'] #\# print(re.findall('a\\c','a\c')) #对于正则来说a\\c确实可以匹配到a\c,但是在python解释器读取a\\c时,会发生转义,然后交给re去执行,所以抛出异常 print (re.findall(r 'a\\c' , 'a\c' )) #r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义 ['a\\c'] print (re.findall( 'a\\\\c' , 'a\c' )) #同上面的意思一样,和上面的结果一样都是['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的结果不是匹配的全部内容,而是组内的内容,?:可以让结果为匹配的全部内容 ['ababab123'] 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' )) #['companies', 'company'] # =================================补充================================= print (re.findall( "<(?P<tag_name>\w+)>\w+</(?P=tag_name)>" , "<h1>hello</h1>" )) #['h1'] print (re.search( "<(?P<tag_name>\w+)>\w+</(?P=tag_name)>" , "<h1>hello</h1>" ).group()) #<h1>hello</h1> print (re.search( "<(?P<tag_name>\w+)>\w+</(?P=tag_name)>" , "<h1>hello</h1>" ).groupdict()) #{'tag_name': 'h1'} print (re.search(r "<(\w+)>\w+</(\w+)>" , "<h1>hello</h1>" ).group()) #<h1>hello</h1> print (re.search(r "<(\w+)>\w+</\1>" , "<h1>hello</h1>" ).group()) #<h1>hello</h1> #补充二 #使用|,先匹配的先生效,|左边是匹配小数,而findall最终结果是查看分组,所有即使匹配成功小数也不会存入结果 #而不是小数时,就去匹配(-?\d+),匹配到的自然就是,非小数的数,在此处即整数 print (re.findall(r "-?\d+\.\d*|(-?\d+)" , "1-2*(60+(-40.35/5)-(-4*3))" )) #找出所有整数['1', '-2', '60', '', '5', '-4', '3'] #找到所有数字: print (re.findall( '\D?(\-?\d+\.?\d*)' , "1-2*(60+(-40.35/5)-(-4*3))" )) # ['1','2','60','-40.35','5','-4','3'] #计算器作业参考:http://www.cnblogs.com/wupeiqi/articles/4949995.html expression = '1-2*((60+2*(-3-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))' content = re.search( '\(([\-\+\*\/]*\d+\.?\d*)+\)' ,expression).group() print (content) #(-3-40.0/5) #为何同样的表达式search与findall却有不同结果: print (re.search( '\(([\+\-\*\/]*\d+\.?\d*)+\)' , "1-12*(60+(-40.35/5)-(-4*3))" ).group()) #(-40.35/5) print (re.findall( '\(([\+\-\*\/]*\d+\.?\d*)+\)' , "1-12*(60+(-40.35/5)-(-4*3))" )) #['/5', '*3'] #看这个例子:(\d)+相当于(\d)(\d)(\d)(\d)...,是一系列分组 print (re.search( '(\d)+' , '123' ).group()) #123 #group的作用是将所有组拼接到一起显示出来 print (re.findall( '(\d)+' , '123' )) #['3'] #findall结果是组内的结果,且是最后一个组的结果 |
re模块提供的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
# ===========================re模块提供的方法介绍=========================== import re #1 print (re.findall( 'e' , 'rose like play' ) ) #['e', 'e'],返回所有满足匹配条件的结果,放在列表里 #2 print (re.search( 'e' , 'rose like play' ).group()) #e,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。 #3 print (re.match( 'e' , 'rose like play' )) #None,同search,不过在字符串开始处进行匹配,完全可以用search+^代替match #4 print (re.split( '[ab]' , 'abcd' )) #['', '', 'cd'],先按'a'分割得到''和'bcd',再对''和'bcd'分别按'b'分割 #5 print ( '===>' ,re.sub( 'a' , 'A' , 'rose like play' )) #===> rose like plAy,不指定n,默认替换所有 print ( '===>' ,re.sub( 'a' , 'A' , 'rose like play' , 1 )) #===> rose like plAy print ( '===>' ,re.sub( 'a' , 'A' , 'rose like play' , 2 )) #===> rose like plAy print ( '===>' ,re.sub( '^(\w+)(.*?\s)(\w+)(.*?\s)(\w+)(.*?)$' ,r '\5\2\3\4\1' , 'rose like play' )) #===> play like rose print ( '===>' ,re.subn( 'a' , 'A' , 'rose like play' )) #===> ('rose like plAy', 1),结果带有总共替换的个数 #6 obj = re. compile ( '\d{2}' ) print (obj.search( 'abc123eeee' ).group()) #12 print (obj.findall( 'abc123eeee' )) #['12'], 重用了obj |