python学习之正则表达式

########正则表达式########
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']

python学习之正则表达式


• . 匹配任何字符
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']

python学习之正则表达式

放斜杠后面可以加不同字符以表示不同特殊意义,也可以用于取消所有的元字符:\
• \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']

python学习之正则表达式


• \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} 更精确地限制了变量的长度是 1­20个字符;
•A|B 可以匹配 A 或 B
•^\d 表示必须以数字开头
• \d$ 表示必须以数字结束
思考
• 判断一个字符串是否是合法的 Email 的方法;
In [19]: r = r'\[email protected]\w+\.com'

In [20]: re.findall(r,'[email protected]  [email protected]  [email protected]')
Out[20]: ['[email protected]', '[email protected]']

python学习之正则表达式
• 判断满足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']
python学习之正则表达式
• 判断一个字符串是否是合法的变量名的方法;
In [35]: r = r'^([_a-zA-Z]\w*$)'

In [36]: re.findall(r,'a2')
Out[36]: ['a2']

python学习之正则表达式

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'
python学习之正则表达式
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'

python学习之正则表达式


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'

python学习之正则表达式



• re.findall(p,text) :将能匹配上的全返回,会返回一个 list
• re.split(p,text) : 按照 p 匹配,并且以匹配到的字符为分隔符切割 text, 返回一个切割后的 list
• re.sub(p,s,text) : 替换,将 p 匹配到的字符替换为 s.
• pattern = re.compile(p) 先编译 p 模式,当正则表达式模式比较复杂的时候,会先编译,然后再使用