刚开始学习正则表达式的时候不太认真,致使没记住多少,后面我老师带咱们搞数据挖掘时,才发现书到用时方恨少,赶忙又把正则表达式梳理了一遍,我我的比较喜欢用一些小例子去理解掌握知识点,因此这篇文章没什么描述,直接经过代码来学习知识,一半批注我都写在代码旁边的注释里了。html
#()表示分组,前面未来对单个字符的重复[1,2],若是你想重复一个子串的话,就能够采用分组的方法
#(字符串)量词 表示对字符串重复
p=re.compile('(ab)+') #匹配一个以上的ab
print(p.search('acabababc').span()) #成功
p=re.compile('(ab|bc)+') #匹配一个以上的ab和bc
print(p.search('acababababc').span())
''' 分组除了当作了表达式外,还有一个重要的功能就是记录。 (和)中匹配的内容会被记录下来,以备之后引用。 在python中,MatchObject的方法group(),start(),end(),span()能够传入一个整型参数来 获得这些记录 记录以0开始计数,而且0表示整个匹配了的表达式,是这些方法的缺省参数,分组从左到右 从1开始计数 ''' p=re.compile('(a(b)c)d') m=p.search('abcd') print(m.groups()) #各分组的值 print(m.group()) print(m.group(0)) print(m.group(1)) print(m.group(2))
结果:python
('abc', 'b') abcd abcd abc b
#(?:....)表示非记录分组,即这个分组不会被记录下来 m=re.match('([abc])+','cbaeee') print(m.group()) print(m.groups()) print(m.group(0)) #0与不写参数效果同样,都是表示 the entire matching string print(m.group(1)) print('=======') n=re.match('(?:[abc])+','abc') #分组不会被记录 print(m.group(0)) print(m.groups()) print(m.group(1))
结果:正则表达式
cba ('a',) cba a ======= cba ('a',) a
''' 在正则表达式中,还能够对分组作出向后引用,是用'\数学'来表示。即\1表示第1个分组,\2表示第二个等等 ''' p=re.compile(r'(\b\w+)\s+\1') #匹配两个一样的单词连着出现,即找一个单词,而且在若干空格,仍是一样的单词 print(p.search('Paris in the the spring').group()) print(p.search('Paris in the the spring').groups())
结果:spring
the the ('the',)
#命名分组 (?P(<name>....)和(?P=name) ''' (?P<name>...)用来定义一个命名分组,他能够经过MatchObject的方法group('name')获得, 同时,在表达式中,也能够以用(?P=name)来表示对它的引用。 ''' p=re.compile(r'(?P<word>\b\w+\b).*(?P=word)') #注意命名分组对它的引用 m=p.search('((((Lots of punctuation aLots)))') print(m.group()) print(m.group('word')) #在方法中以引用 print(m.group(0)) print(m.group(1)) print(m.span('word'))
结果app
Lots of punctuation aLots Lots Lots of punctuation aLots Lots (4, 8)
#(?=...)后向界定/零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式
#但它不包括这些表达式,就像\b,^,$那样用于指定一个位置,这个位置应该知足必定的条件(断言)
#所以他们也被成为0度断言
#好比\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing之外的部分)
p=re.compile('(Rui) (?=Zhang)') #匹配Rui后面跟zhang时的状况不包括张在内
print(p.search('hi,Rui Zhang').group())
print(p.search('hi,Rui Zhang').group(0))
print(p.search('hi,Rui Zhang').group(1))
print(p.search('hi,Rui Zhang').groups()) #全部知足条件的分组
print(p.search('hi,Rui Zhou').group()) #匹配失败
#(?!...) ''' 后向非界定/零宽度负预测先行断言。断言此位置的后面不能匹配表达式 例如:\d{3}(?!\d)匹配三位数字,并且这三位数字的后面不能是数字 ''' p=re.compile(r'Rui(?!Zhang)') #匹配Rui后面不是Zhang的状况 print(p.search('hi,Rui Zhou').group()) #成功 print(p.search('hi,Rui Zhang').group()) #失败
结果:ide
Rui
#(?<!...)前向非界定/零宽度负回顾后发断言,断言此位置的前面而不能匹配表达式 #例如:(?<![a-z])\d(7)匹配前面不是小写字母的七位数字 p=re.compile(r'(?<!Rui )Zhang') print(p.search('hi,Shan Zhang').group()) #成功 print(p.search('hi,Rui Zhang').group()) #匹配失败结果:
Zhang
#(?iLmsux) ''' 在'i','L','m','s','u','x'中的一个或多个,它不匹配任何字串,而是表示对应(re.I,re.M,re.S,re.X,re.U)的6种选择 此处编译选项'i'等价于IGNORECASE,L等价于LOCAL,m等价 于MULTLINE,s的等价于DOTALL,u等价于UNICODE,x等价于VERBOSE 请注意他们的大小写,在使用时能够指定一部分,不如只指定忽略大小写,可写为'(?i)',要同时忽略大小写并使用多行模式 另外要注意选项的有效范围是整条规则,即写在规则的任何地方,选项都会对所有整条正则式有效 ''' p=re.compile('(?m)^From:') #与使用re.M选项是同样的 print(p.search('hi,\nFrom:rui').span())
结果:学习
(4,9)
# I IGNORECASE 忽略大小写 # L LOCAL字符集本地化。这个功能是为了支持多语言版本的字符集使用环境的 #好比在转义字符\w,在英文环境下,它表明[a-zA-Z0-9],即全部英文字符和数字 #若是在一个法语环境下使用,缺省设置下,不能匹配'e'或‘c’.加上这L选项和就能够匹配了,不过这个对弈中文环境彷佛没什么用,它仍然不能匹配 # M MULTLINE多行匹配,在这个模式下‘’(表明字符串开头)和‘$’(表明字符串结尾)将可以匹配多行匹配的状况,成为行首和行尾标记 s='123 56\4n789 012\n345 678' rc=re.compile('^\d+') #匹配一个位于开头的数字,没有使用M选项 \d[0-9] print(rc.findall(s)) rcm=re.compile('^\d+',re.M) #找到了三个行首的数字 print(rcm.findall(s))结果:
['123'] ['123', '345']
''' 一样,对于'$'来讲。没有使用M选项,它将匹配最后一个行尾的数字,即'678' 加上之后,就能匹配三个行尾的数字 456 012 和678 了 ''' rc=re.compile('\d+$') print(rc.findall(s)) rcm=re.compile('\d+$',re.M) print(rcm.findall(s))结果:
['678'] ['012', '678']
# S DOTALL ‘.’号将匹配全部的字符,缺省状况下'.'匹配除换行符'\n'之外的全部字符 # U UNICODE \w,\W,\b,\B,\D,\s和\S都将使用Unicode # X VERBOSE 这个选项忽略规则表达式中的空白,并容许使用‘#’来引导一个注释,这样可让你把规则写的更美观些。