Python 正则表达式

「正则表达式」

一 简介:

正则表达式,是一个特殊的字符序列,又称规则表达式(英语:Regular Expression,在代码中常简写为regex、regexp 或RE),本质而言是一种小型的,高度专业化的编程语言,在(Python)中它内嵌在Python中,并通过RE模块实现;能帮你方便的检查一个字符串是否与某种模式(规则)匹配。

正则表达式,通常被用来检索、替换那些符合某个模式(规则)的文本;正则表达式模式被编译成一系列的字节码,然后用C编写的匹配引擎执行。

Python 自1.5版本起增加了re 模块,re 模块使Python语言拥有全部的正则表达式功能。

使用正则表达式进行匹配的流程:

 

 

 

 

 

 

# 导入re正则模块
import re

 二 字符匹配:

  正则表达式涉及到的字符,分为普通字符和元字符;元字符是具有特殊功能的字符。

1.普通字符: 大多数字符和字母都可以看作是普通字符。

#实例:
>>> re.findall('jesson',"dsjkdfjsWRFDd jessonFFEEGsddeed')  
    # 这里调用了方法re.findall() 该方法的主要功能是,符合条件的结果全部匹配;下文会单独介绍。
 >>>['jesson'] #完全匹配 这里基本没有用到正则

2. 元字符:(11个)

.   ^   $  *  +  ?  {}  []  \  |  ()

  (1)元字符“.” 通配符,可以代指所有字符,除了换行符号"\n",一个点,对应一个字符

#实例1:
ret = re.findall('w...d','hello world')
print(ret)
#实例2:
ret = re.findall('w...d','hello wor\nd') # 不能匹配“\n”
print(ret) # 输出结果为空[],说明"."匹配不到"\n"

  (2)元字符“^” 从整个字符串开头的地方匹配

#实例:
ret = re.findall('^h...o','hello world')
print(ret) #输出结果:['hello']

  (3)元字符“$” 从整个字符串的结尾开始匹配。     可以理解成:从后往前匹配

#实例1:
ret = re.findall('h...o$','hello world awdx')
print(ret) # 输出结果为空 从整个字符的结尾,不是hello的结尾
#实例2:
ret = re.findall('a..x$','hello world awdx')
print(ret) #输出结果:['awdx'] 匹配成功

  (4)元字符“*” 重复匹配 (表达式中的*表示重复*号前边字符 个数从0到正无穷)

#实例1:想匹配的 以a开头,以li 结尾的字符
#普通写法:
ret = re.findall('a........li','hello world alex88888li')
print(ret) # 输出结果:['alex88888li']
#采用“*”来写:
ret = re.findall('a.*li','hello world alex88888li')
print(ret) # 输出结果:['alex88888li']
#实例2:
ret = re.findall('ba*','sjfjslafjbaaaaaaaaaaaa')
print(ret) # 输出结果:['baaaaaaaaaaaa']

ret = re.findall('f*','hellof')
print(ret) # 输出结果:['', '', '', '', '', 'f', '']
ret = re.findall('f*','hello')
print(ret) # 输出结果:['', '', '', '', '', '']
# 表示取*前边的f,如果有f,可以匹配出,但是,注意没有f的情况下,也会匹配,结果为none值

 (5)元字符"+" 表示匹配“+”前边的字符 个数从1到正无穷都能匹配

 

#实例1:
ret = re.findall('ab+','dsljfsfjslfaaa')
print(ret) # 输出结果为空 [] 说明没有找到字符b
ret = re.findall('ab+','dsljfsfjslfaaabbbbbbbbbbb')
print(ret) # 输出结果:['abbbbbbbbbbb']
#实例2:
ret = re.findall('a+b','adadfwdbaaaaaablkls;flsabb')
print(ret) # 输出结果:['aaaaaab', 'ab']

ret = re.findall('f+','hellof')
print(ret) # 输出结果:['f']

ret = re.findall('f+','fhello')
print(ret) # 输出结果:['f']

ret = re.findall('f+','hello')
print(ret) # 输出结果:[]
# 上述实例说明:取+前边的f 个数,如果有f 则匹配出,如果没有f,匹配结果为空,对比*

 (6)元字符"?" 表示匹配"?"前边的字符 个数为闭区间[0,1] 即:0个或者1个

#实例:
ret = re.findall('a?b','aaaabkshkgabsdbannndbab')
print(ret) # 输出结果:['ab', 'ab', 'b', 'b', 'ab']

 (7)元字符"{}" 表示匹配"{}"前边的字符 指定个数为"{}"里边的数值

#实例1:
ret = re.findall('a{5}b','aaaaab') #匹配字符a 并且指定个数为5 即:表示匹配连续的5个a加上b
print(ret) # 输出结果:['aaaaab']
#实例2:
ret = re.findall('a{}b','aaaaab') # 如果中括号里边不加任何值 则表示{} 按照普通字符来匹配。
print(ret) # 输出结果为空[] 因为字符串'aaaaab'中没有"{}",将字符串'aaaaab'改成'aaaaa{}b' 就可以匹配到了。
#实例3:
ret = re.findall('a{1,3}b','jksjablskflskaabdlsfaaaaab') # 大括号里边可以加参数{1,3}表示字符个数的范围。
print(ret) # 输出结果:['ab', 'aab', 'aaab']
#实例4:
ret = re.findall('a{1,3}b','dlsfaaaaab') # 如果目标匹配对象中,只有一个 个数大于等于3的字符串 那么默认匹配显示最多;即:aab 而不是ab 或者 abb [贪婪匹配]
print(ret) # 输出结果:['aaab']

 (8)元字符"[]" 表示一个字符集,它常被用来指定一个字符类别,所谓字符类别就是你想匹配的一个字符集。字符可以单个列出,也可以用“-”号分隔的两个给定字符来表示一个字符区间。例如:[abc]将匹配"a","b",或者"c"中的任意一个字符;也可以用区间[a-c]来表示同一个字符集,和前者效果一致。如果只想匹配小写字符则可以写成[a-z]。

#实例1:
ret = re.findall('a[c,d,e]x','adx') # []里边的内容 表示或者的关系 也就是说只要出现任意中括号中的内容 就会匹配。
print(ret)
#实例2:
ret = re.findall('[1-9,a-z,A-Z]','123jskdjJWKJKJKS')
# ret = re.findall('[1-9a-zA-Z]','123jskdjJWKJKJKS') # 输出结果和上边的相同 只是解释器判断的逻辑顺序不同
print(ret) # 输出结果:['1', '2', '3', 'j', 's', 'k', 'd', 'j', 'J', 'W', 'K', 'J', 'K', 'J', 'K', 'S']
#实例3: "^" 尖角号放在中括号中 表示:除了XXX字符 即:非
ret = re.findall('[^4,5]','flja4slfj5') # 表示非4 或则 非5
print(ret) # 输出结果:['f', 'l', 'j', 'a', 's', 'l', 'f', 'j']

 (9)元字符"\" 反斜杠

反斜杠后边跟元字符,去除其特殊功能反斜杠 
反斜杠后边跟普通字符,实现其特殊功能
\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 #表示:匹配一个单词边界,即:匹配字符和空格间的位置
#实例:
print(re.findall('\w','fada sess'))
print(re.findall('\W','fada sess')) # 匹配任何 非 字母数字字符 这里相当于“空格”
print(re.findall('a\b','fada sess')) #
print(re.findall(r'a\b','fada sess')) # 加r表示 原生字符串读取

 (10)元字符"()" 表示:分组 将括号中的内容 当作整体来对待

#实例1:
print(re.findall('(as)','ksjdksjasas'))
print(re.findall('(as)+','ksjdksjasas'))
print(re.search('(as)','ksjdksjasas').group())
print(re.search('(as)+','ksjdksjasas').group())
# 输出结果对比:
# ['as', 'as']
# ['as']
# as
# asas

#实例2:
print(re.search('(as)','ksjdksjasas').group())
print(re.search('(as)|222','ksjdksjasas222').group()) # | 管道符表示或者
# 输出结果:相同 因为管道符前边的匹配成功后,后边的条件“222”就不会去匹配。
# as
# as

#实例3:
ret = re.search('(?P<id>\d{3})/(?P<name>\w{6})','skejksd001/jessonadf002/pitterxd')
print(ret.group())
print(ret.group('id')) # group('')添加组成员参数
print(ret.group('name'))
# 输出结果:
# 001/jesson
# 001
# jesson

#.findall() 对比上方的 .search()
ret = re.findall('(?P<id>\d{3})/(?P<name>\w{6})','skejksd001/jessonadf002/pitterxd')
print(ret)
# 输出结果:
#[('001', 'jesson'), ('002', 'pitter')]

 (11)元字符"|" 管道符 表示逻辑:或者

print(re.search('(as)|222','ksjdksjasas222').group())
print(re.findall('(as)|222','jasas222'))

元字符功能总结:

"."  通配符,匹配任意单个字符,默认不会匹配\n换行符,加re.S可以实现匹配换行符
"^"  从整个字符串开头的地方匹配
"$"  从整个字符串的结尾开始匹配 即:从后往前匹配
"*"  重复匹配 (表示匹配重复的*号前边字符 个数从0到正无穷)
"+"  匹配“+”前边的字符 个数从1到正无穷都能匹配
"?"  匹配"?"前边的字符 个数为闭区间[0,1] 即:0个或者1个
"{}" 匹配"{}"前边的字符 指定个数为"{}"里边的数值
"[]" 表示一个字符集,常被用来指定匹配一个字符类别 例如:[0-9,a-z,A-Z]
"\"  反斜杠 后边跟元字符,去除其特殊功能;后边跟普通字符,实现其特殊功能
"()" 表示:分组 将括号中的内容 当作整体来对待
"|"  管道符 表示逻辑:或者 常常配合分组使用;例如:print(re.findall('(as)|222','jasas222'))

 三 方法

 (1) 方法:findall() (即:全部找到,返回的是一个列表)

#实例:
s = 'hello world'
ret = re.findall('w\w{3}d','hello world')
print(ret)

 (2) 方法:search() (即:匹配出第一个满足条件的结果,返回的是一个对象) 可以通过调用.group()方法,可以将匹配的结果输出。

#实例:
ret = re.search('h..','hello hello world')
print(ret) # 输出结果:<_sre.SRE_Match object; span=(0, 3), match='hel'>
ret1 = re.search('h..','hello hello world').group()
print(ret1) # 输出结果:hel 只输出第一个符合条件的结果

 (3)方法:match() 返回匹配到的第一个对象,只在字符串开始匹配。同样,可以通过调用.group()方法,可以将匹配的结果输出。

#注意:
# match()  只检测RE是不是在string的开始位置匹配, 
# search() 会扫描整个string查找匹配;
# 也就是说match() 只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功的话,match()就返回none

 

#实例:
ret = re.match('asd','asdhskdjfksji')
print(ret) # 输出结果:<_sre.SRE_Match object; span=(0, 3), match='asd'>返回的是一个对象。
ret1 = re.match('asd','asdhskdjfasdksjiasd').group()
print(ret1) # 输出结果:asd 调用.group()方法,只返回匹配的第一个结果。

 (4)方法:split() 分隔符 对比字符串里边的split方法。

实例1:
ret = re.split('j','dsdhsjdwakjdswddkdjsjwkjd')
print(ret) # 输出结果:['dsdhsjd', 'jds', 'jd'] 以k为分隔符,将字符分隔,返回结果。
实例2:
ret1 = re.split('[j,k]','dsdhsjdwakjdswddkdjsjwkjd')
print(ret1) # 输出结果: ['dsdhs', 'dwak', 'dswddkd', 's', 'wk', 'd']

['dsdhs', 'dwak', 'dswddkd', 's', 'wk', 'd']
['dsdhs', 'dwa', '', 'dswdd', 'd', 's', 'w', '', 'd']
# 对比上方的两个输出结果,可以发现:匹配的执行顺序是,先以中括号中的第一个规则字符“j”进行匹配,
# 然后,在分隔结果的基础上,再以第二个规则字符“k”,对其进行分隔。匹配结果中单独的字符"k" 被分隔后,输出空''

 (5)方法: sub() 替换;类似字符串中的replace()方法。

ret = re.sub('a..x','jesson','hello,alex')
print(ret) # 输出结果:hello,jesson

 (6)方法: compile(strPattern[,flag]): 这个方法是Pattern类的工厂方法,用于将字符串形式的正则表达式编译为Pattern对象。第二个参数flag是匹配模式,取值可以使用 按位 或 运算符“|” 表示同时生效。

简单来说,该方法的功能就是:可以把正则表达式编译成一个正则表达式对象。一定程度,可以提高效率。

#实例:
# 未采用compile()方法:
ret = re.findall('\.com','www.baidu.com___www.jingdong.com')
print("ret",ret)
# 采用compile()方法:
obj = re.compile('\.com')
ret1 = obj.findall('www.baidu.com___www.jingdong.com')
print("ret1",ret1)
# 两次输出结果:相同
# ret ['.com', '.com']
# ret1 ['.com', '.com']

 

posted @ 2016-09-11 11:51  hello-Jesson  阅读(3071)  评论(0编辑  收藏  举报