########正则表达式########
1.正则表达式
正则表达式是一种用来匹配字符串的强有力的武器。
它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
基本模式
• 字面模式: 就是字面长量,就代表其本身
In [7]: r = 'yu\\n'
In [9]: s = 'di wu ling yu\\n'
In [10]: import re
In [11]: re.findall(r,s)
Out[11]: []
In [12]: r1 = r'yu\\n'
In [13]: re.findall(r1,s)
• . 匹配任何字符
In [14]: s = 'top tal tool cat'
In [15]: r ='t.'
In [16]: re.fin
re.findall re.finditer
In [16]: re.findall(r,s)
Out[16]: ['to', 'ta', 'to']
In [17]: r ='t..'
In [18]: re.findall(r,s)
• \w 匹配任何字母数字字符,类似[a-zA-Z0-9]
In [10]: import re
In [11]: s = 'di y1wu y_ling yun'
In [12]: r = 'y.\w'
In [13]: re.findall(r,s)
• \W 匹配非字母数字字符,类似[^a-zA-Z0-9]
• \s 匹配任何空白字符,类似[\t\n\r\f\v]
• \S 匹配非空白字符,类似[^\t\n\r\f\v]
• \d 匹配任何十进制数字,类似[0-9]
• ^ 开头 $ 结尾
• \ 转义字符
.次数的匹配
次数的匹配 , 匹配其前面的字符出现的次数 :
• * 0 次或多次
• + 一次或多次
• ? 零次或一次
• {n} 出现 n 次
• {m,n} 出现 m 到 n 次
.中括号
• 中括号用于指向一个字符集合
• 中括号可以使用元字符
• 中括号中的. 表示其字面意思
[a-z] [A-Z] [0-9] [A-Za-z]
• [0-9a-zA-Z\_] 可以匹配一个数字、字母或者下划线;
• [0-9a-zA-Z\_]+ 可以匹配至少由一个数字、字母或者下划线组成的字符串;
• [a-zA-Z\_][0-9a-zA-Z\_]{0, 19} 更精确地限制了变量的长度是 120个字符;
•A|B 可以匹配 A 或 B
•^\d 表示必须以数字开头
• \d$ 表示必须以数字结束
思考
• 判断一个字符串是否是合法的 Email 的方法;
In [19]: r = r'\w+@\w+\.com'
In [20]: re.findall(r,'hello@westos.org hello@westos.com westos@westos.com')
Out[20]: ['hello@westos.com', 'westos@westos.com']
![](https://img-blog.csdn.net/20170715231219148?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3NkbjA2Ng==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
• 判断满足029-1234567这样要求的电话号码的方法;
In [21]: r = r'^\d{3}-\d{7}'
In [22]: re.findall(r,'029-1234567 0291-2345678 029-eer23efew')
Out[22]: ['029-1234567']
![](https://img-blog.csdn.net/20170715231245403?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3NkbjA2Ng==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
• 判断一个字符串是否是合法的变量名的方法;
In [35]: r = r'^([_a-zA-Z]\w*$)'
In [36]: re.findall(r,'a2')
Out[36]: ['a2']
re.match(r, 'hello')
re.match(r, 'westos')
match() 方法判断是否匹配,如果匹配成功,返回一个 Match对象,否则返回 None 。
In [37]: r = r't.p'
In [38]: p = re.compile(r)
In [39]: re.findall(p,'top tap toop tyi')
Out[39]: ['top', 'tap']
In [40]: a = re.match(p,'top tap toop tyi')
In [41]: a.gr
a.group a.groupdict a.groups
In [41]: a.group()
Out[41]: 'top'
![](https://img-blog.csdn.net/20170715231357350?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3NkbjA2Ng==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
5.分组
m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
m.group(0)
m.group(1)
m.group(2)
6.贪婪匹配
正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符
>>> re.match(r'^(\d+)(0*)$', '102300').groups()
('102300', '')
正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符
>>> re.match(r'^(\d+)(0*)$', '102300').groups()
('102300', '')
\d+ 采用贪婪匹配,直接把后面的 0 全部匹配了,结果 0* 只能匹配空字符串贪婪匹配正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符
>>> re.match(r'^(\d+)(0*)$', '102300').groups()
('102300', '')
• \d+ 采用贪婪匹配,直接把后面的 0 全部匹配了,结果 0* 只能匹配空字符串
• 必须让 \d+ 采用非贪婪匹配(也就是尽可能少匹配),才能把后面的 0 匹配出来,加个 ? 就可以让 \d+ 采用非贪婪匹配
7.编译
当我们在 Python 中使用正则表达式时,re 模块内部会干两件事情:
1. 编译正则表达式,如果正则表达式的字符串本身不合法,会报错;
2. 用编译后的正则表达式去匹配字符串。
重复使用几千次,出于效率的考虑,我们可以预编译该正则表达式。
r = r'hello'
r_compile = r.compile(r)
r_compile .match()
练习
基础版:有一个日志文件access.log,统计访问前十的 IP 地址和访问次数。
升级版:有多个日志文件access.log,统计访问前十的 IP 地址和访问次数。
总结
• re.match(p,text) :p 为正则表达式模式, text 要查找的字符串,会返回一个match 对象
• re.search(p,text) : 只要在 text 中匹配到了 p 就返回,只返回第一个匹配到的
In [49]: a = re.search(r'hello','westos hello')
In [50]: a.group()
Out[50]: 'hello'
In [49]: a = re.search(r'hello','westos hello')
In [50]: a.group()
In [51]: a = re.match(r'hello','westos hello')
In [52]: a.group()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-52-af218c045ead> in <module>()
----> 1 a.group()
AttributeError: 'NoneType' object has no attribute 'group'
In [53]: a = re.match(r'hello','hello westos hello')
In [54]: a.group()
• re.findall(p,text) :将能匹配上的全返回,会返回一个 list
• re.split(p,text) : 按照 p 匹配,并且以匹配到的字符为分隔符切割 text, 返回一个切割后的 list
• re.sub(p,s,text) : 替换,将 p 匹配到的字符替换为 s.
• pattern = re.compile(p) 先编译 p 模式,当正则表达式模式比较复杂的时候,会先编译,然后再使用
1.正则表达式
正则表达式是一种用来匹配字符串的强有力的武器。
它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
基本模式
• 字面模式: 就是字面长量,就代表其本身
In [7]: r = 'yu\\n'
In [9]: s = 'di wu ling yu\\n'
In [10]: import re
In [11]: re.findall(r,s)
Out[11]: []
In [12]: r1 = r'yu\\n'
In [13]: re.findall(r1,s)
Out[13]: ['yu\\n']
• . 匹配任何字符
In [14]: s = 'top tal tool cat'
In [15]: r ='t.'
In [16]: re.fin
re.findall re.finditer
In [16]: re.findall(r,s)
Out[16]: ['to', 'ta', 'to']
In [17]: r ='t..'
In [18]: re.findall(r,s)
Out[18]: ['top', 'tal', 'too']
• \w 匹配任何字母数字字符,类似[a-zA-Z0-9]
In [10]: import re
In [11]: s = 'di y1wu y_ling yun'
In [12]: r = 'y.\w'
In [13]: re.findall(r,s)
Out[13]: ['y1w', 'y_l', 'yun']
• \W 匹配非字母数字字符,类似[^a-zA-Z0-9]
• \s 匹配任何空白字符,类似[\t\n\r\f\v]
• \S 匹配非空白字符,类似[^\t\n\r\f\v]
• \d 匹配任何十进制数字,类似[0-9]
• ^ 开头 $ 结尾
• \ 转义字符
.次数的匹配
次数的匹配 , 匹配其前面的字符出现的次数 :
• * 0 次或多次
• + 一次或多次
• ? 零次或一次
• {n} 出现 n 次
• {m,n} 出现 m 到 n 次
.中括号
• 中括号用于指向一个字符集合
• 中括号可以使用元字符
• 中括号中的. 表示其字面意思
[a-z] [A-Z] [0-9] [A-Za-z]
• [0-9a-zA-Z\_] 可以匹配一个数字、字母或者下划线;
• [0-9a-zA-Z\_]+ 可以匹配至少由一个数字、字母或者下划线组成的字符串;
• [a-zA-Z\_][0-9a-zA-Z\_]{0, 19} 更精确地限制了变量的长度是 120个字符;
•A|B 可以匹配 A 或 B
•^\d 表示必须以数字开头
• \d$ 表示必须以数字结束
思考
• 判断一个字符串是否是合法的 Email 的方法;
In [19]: r = r'\w+@\w+\.com'
In [20]: re.findall(r,'hello@westos.org hello@westos.com westos@westos.com')
Out[20]: ['hello@westos.com', 'westos@westos.com']
• 判断满足029-1234567这样要求的电话号码的方法;
In [21]: r = r'^\d{3}-\d{7}'
In [22]: re.findall(r,'029-1234567 0291-2345678 029-eer23efew')
Out[22]: ['029-1234567']
• 判断一个字符串是否是合法的变量名的方法;
In [35]: r = r'^([_a-zA-Z]\w*$)'
In [36]: re.findall(r,'a2')
Out[36]: ['a2']
4.re 模块
r = r'hello're.match(r, 'hello')
re.match(r, 'westos')
match() 方法判断是否匹配,如果匹配成功,返回一个 Match对象,否则返回 None 。
In [37]: r = r't.p'
In [38]: p = re.compile(r)
In [39]: re.findall(p,'top tap toop tyi')
Out[39]: ['top', 'tap']
In [40]: a = re.match(p,'top tap toop tyi')
In [41]: a.gr
a.group a.groupdict a.groups
In [41]: a.group()
Out[41]: 'top'
5.分组
m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
m.group(0)
m.group(1)
m.group(2)
6.贪婪匹配
正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符
>>> re.match(r'^(\d+)(0*)$', '102300').groups()
('102300', '')
正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符
>>> re.match(r'^(\d+)(0*)$', '102300').groups()
('102300', '')
\d+ 采用贪婪匹配,直接把后面的 0 全部匹配了,结果 0* 只能匹配空字符串贪婪匹配正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符
>>> re.match(r'^(\d+)(0*)$', '102300').groups()
('102300', '')
• \d+ 采用贪婪匹配,直接把后面的 0 全部匹配了,结果 0* 只能匹配空字符串
• 必须让 \d+ 采用非贪婪匹配(也就是尽可能少匹配),才能把后面的 0 匹配出来,加个 ? 就可以让 \d+ 采用非贪婪匹配
7.编译
当我们在 Python 中使用正则表达式时,re 模块内部会干两件事情:
1. 编译正则表达式,如果正则表达式的字符串本身不合法,会报错;
2. 用编译后的正则表达式去匹配字符串。
重复使用几千次,出于效率的考虑,我们可以预编译该正则表达式。
r = r'hello'
r_compile = r.compile(r)
r_compile .match()
练习
基础版:有一个日志文件access.log,统计访问前十的 IP 地址和访问次数。
升级版:有多个日志文件access.log,统计访问前十的 IP 地址和访问次数。
总结
• re.match(p,text) :p 为正则表达式模式, text 要查找的字符串,会返回一个match 对象
• re.search(p,text) : 只要在 text 中匹配到了 p 就返回,只返回第一个匹配到的
In [49]: a = re.search(r'hello','westos hello')
In [50]: a.group()
Out[50]: 'hello'
In [49]: a = re.search(r'hello','westos hello')
In [50]: a.group()
Out[50]: 'hello'
In [51]: a = re.match(r'hello','westos hello')
In [52]: a.group()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-52-af218c045ead> in <module>()
----> 1 a.group()
AttributeError: 'NoneType' object has no attribute 'group'
In [53]: a = re.match(r'hello','hello westos hello')
In [54]: a.group()
Out[54]: 'hello'
• re.findall(p,text) :将能匹配上的全返回,会返回一个 list
• re.split(p,text) : 按照 p 匹配,并且以匹配到的字符为分隔符切割 text, 返回一个切割后的 list
• re.sub(p,s,text) : 替换,将 p 匹配到的字符替换为 s.
• pattern = re.compile(p) 先编译 p 模式,当正则表达式模式比较复杂的时候,会先编译,然后再使用