正则(1)基础语法
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个符串是否与某种模式匹配
python 导入:import re 模块
正则的表达式:
字符分类:
\d 0-9数字
\D 除了0-9以外的任何字符
\w 任何字母数字或下划线(单词,广义上的内容)
\W 除了字母数字或下划线以外的任何字符
\s 空格,制表符,换行(空白)
\S 除了空格,制表符,换行以外的任何字符
^ 从开头匹配
$ 从结尾匹配
\A 仅匹配字符串开头
\Z 仅匹配字符串结尾
. 通配符,任意字符(除\n换行) 例子:r'.at'
? 可选匹配,0-1次匹配 例子:r'(abc)?'
* 可选匹配,0-n次匹配
+ 可选匹配,1-n次匹配
[] 字符集,对应位置可以是字符集中任意位置,可以[abc]或[a-c]
{m} 代表次数 例:r'(abc){3}'
{m,n} 代表次数,有m没n,m-无限次,没m有n,0-n次 例:r'(abc){3}'
创建正则表达对象:
例如匹配区号+电话号码
phonenum = re.compile(r'\d\d\d')
基本要素的:
import re print(re.match('www', 'www.abc.com')) print(re.match('www', 'www.abc.com').span()) print(re.match('www', 'www.abc.com').group())
结果:
<re.Match object; span=(0, 3), match='www'> (0, 3) www
正则表达式表达模式:
利用括号分组:
import re:
phonenum = re.compile(r'(\(\d\d\))(\d\d\d\d)-(\d\d\d\d)')
mo = phonenum.search('myphone number is (86)1681-5456')
print(mo.group())
print(mo.groups())
结果:
(86)1681-5456
('(86)', '1681', '5456')
注:\(和\)两个转义字符匹配()
管道 | 匹配意为“或”:
import re phonenum = re.compile(r'\d\d\d|number') mo1 = phonenum.search('myphone number is (025)1681-5456') mo2 = phonenum.search('(025)1681-5456 is myphone number') print(mo1.group()) print(mo2.group())
结果:
number 025
正则表达式修饰符 - 可选标志:
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |
re方法:
search方法:
re.search 扫描整个字符串并返回第一个成功的匹配。
def search(pattern, string, flags=0):
例子:
import re phonenum = re.compile(r'\d\d\d\d') mo = phonenum.search('myphone number is 1681 5456') print(mo) print(mo.group())
结果:
<re.Match object; span=(18, 22), match='1681'> 1681
re.match方法:
re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。
def match(pattern, string, flags=0):
pattern:匹配的正则表达式
string :需要被匹配的文字
falg :参数
import re line = "Cats are smarter than dogs" matchObj = re.match(r'(.*) are (.*?).*',line) print("matchObj.group() : ", matchObj) print("matchObj.group() : ", matchObj.group()) print("matchObj.group(1) : ", matchObj.group(1))
结果:
matchObj.group() : <re.Match object; span=(0, 26), match='Cats are smarter than dogs'> matchObj.group() : Cats are smarter than dogs matchObj.group(1) : Cats
re.match与re.search的区别:
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
import re line = "Cats are smarter than dogs"; matchObj = re.match(r'dogs', line, re.M | re.I) if matchObj: print("match --> matchObj.group() : ", matchObj.group()) else: print("No match!!") matchObj = re.search(r'dogs', line, re.M | re.I) if matchObj: print("search --> matchObj.group() : ", matchObj.group()) else: print("No match!!")
sub()方法替换字符:
def sub(self, repl, string, count=0):
有三个参数
self指的是正则
repl是指替代原来字符的现有文字
string 是需要被替代的字符串
import re print(re.sub(r'Bob \w+',"Man","Bob Allen is so hot"))
结果:
Man is so hot
如果repl是函数:
import re # 将匹配的数字乘于 2 def double(matched): value = int(matched.group('value')) return str(value * 2) s = '衬衫的价格是9镑15便士' print(re.sub('(?P<value>\d+)', double, s))
衬衫的价格是18镑30便士
findall:
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
注意: match 和 search 是匹配一次 findall 匹配所有。
def findall(pattern, string, flags=0):
例子:
import re telephonenum=''' 公司的联系电话 025-55555 010-55555 ''' # 400-5050-4008 #没有分组的正则表示 regexrule1=r'\d\d\d-\d\d\d\d\d' regexrule2=r'(\d\d\d)-(\d\d\d\d\d)' regexrule3=r'\d{3}-\d{5}' print(re.findall(regexrule1,telephonenum)) print(re.findall(regexrule2,telephonenum)) print(re.findall(regexrule3,telephonenum))
结果:
['025-55555', '010-55555'] [('025', '55555'), ('010', '55555')] ['025-55555', '010-55555']
注:在调用一个没有分组的正则表达式的时候,会显示['025-55555', '010-55555']
在调用一个分组的正则表达式的时候,会显示[('025', '55555'), ('010', '55555')]
re.finditer
和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回
import re telephonenum=''' 公司的联系电话 025-55555 010-55555 ''' # 400-5050-4008 #没有分组的正则表示 regexrule1=r'\d{3}-\d{3,5}' for i in re.finditer(regexrule1,telephonenum): print(i.group())
025-55555 010-55555
注:finditer函数和findall函数的区别是,findall返回所有匹配的字符串,并存为一个列表,而finditer则并不直接返回这些字符串,而是返回一个迭代器。
简单的说,就是finditer返回了一个可调用的对象,使用 for i in finditer()的形式,可以一个一个的得到匹配返回的 Match对象。这在对每次返回的对象进行比较复杂的操作时比较有用。
re.split
split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:
import re print(re.split('\W+', 'runoob, runoob, runoob.')) print(re.split('\W+', ' runoob, runoob, runoob.')) print(re.split('(\W+)', ' runoob, runoob, runoob.')) print(re.split('\W+', ' runoob, runoob, runoob.', 1)) print(re.split('a+', 'hello world')) # 对于一个找不到匹配的字符串而言,split 不会对其作出分割 ['hello world']
结果:
['runoob', 'runoob', 'runoob', ''] ['', 'runoob', 'runoob', 'runoob', ''] ['', ' ', 'runoob', ', ', 'runoob', ', ', 'runoob', '.', ''] ['', 'runoob, runoob, runoob.'] ['hello world']
贪心匹配和非贪心匹配:
pyhton默认贪心匹配,尽量匹配长的字符串,?改变为非贪心,尽量匹配短的字符串
import re s="gaxxIxxefahxxlovexxhoghexxpythonxxghaweoif" print(re.compile('xx(.*)xx').findall(s)) print(re.compile('xx(.*?)xx').findall(s))
结果:
['Ixxefahxxlovexxhoghexxpython'] ['I', 'love', 'python']