正则表达式,可以取数据
正则有匹配贪婪性,照多了匹配
>>> import re
>>> s="I am 19 years old"
>>> re.search(r"\d+",s)
<_sre.SRE_Match object at 0x0000000002F63ED0>
>>> re.search(r"\d+",s).group()
'19'
>>>
>>> s="I am 19 years 20 old 30"
>>> re.findall(r"\d",s)
['1', '9', '2', '0', '3', '0']
>>> re.findall(r"\d+",s)
['19', '20', '30']
可以匹配数据,取数据,
判断句子里是否包含指定字符串
re.match(r"\d+","123abc")里面的r最好带上,以防止转义字符影响
r”\d”匹配数字
>>> re.match(r"\d+","123abc")
<_sre.SRE_Match object at 0x0000000002F63ED0>
>>> re.match("\d+","123abc")
<_sre.SRE_Match object at 0x000000000306B030>
>>> re.match("\d+","a123abc")
>>> re.match("\d+","a123abc")
>>> re.match("\d+","123abc").group()
'123'
>>> re.match("\d+","123abc 1sd").group()
'123'
Re.search(r“\d+”)任意位置符合就返回
Re.findall(r“\d+”),也是任何位置匹配就返回
Re.match(r“\d+”),从字符串第一个位置开始匹配
>>> re.match("\d+","123abc 1sd").group()
'123'
>>> re.search("\d+","123abc 1sd").group()
'123'
>>> re.search("\d+","a123abc 1sd").group()
'123'
>>> re.match("\d+","a123abc 1sd").group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>> re.match("\d+","a123abc 1sd")
>>> re.findall(r"\d+","a1b2c3")
['1', '2', '3']
>>> re.match(r"\d+","a1b2c3")
r”\D”匹配非数字
re.match(r"\D+","a1b2c3")匹配非数字
>>> re.match(r"\D+","a1b2c3").group()
'a'
>>> re.match(r"\D+","abc1b2c3").group()
'abc'
re.match(r"\D+\d+","ab12 bb").group()匹配”ab12 bb”,匹配ab12
>>> re.match(r"\D+\d+","ab12 bb").group()
'ab12'
r”\s”匹配空白
re.match(r"\s+","s")匹配空白,match函数从字符串的第一个字符就开始匹配
>>> re.match(r"\s+","ab12 bb").group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>> re.match(r"\s+"," bb").group()
r”\S”匹配非空白
re.match(r"\S+","eee bb")非空白,直到出现空白式
>>> re.match(r"\S+","eee bb").group()
'ee
>>> print 'a'#str方法
a
>>> 'a'#repr方法
'a'
r"\w+"匹配数字和字母
re.findall(r"\w+"," sdf")数字和字母
>>> re.findall(r"\w+"," sdf")
['sdf']
>>> re.findall(r"\w+"," 12 sdf")
['12', 'sdf']
>>> re.findall(r"\w+"," 12 sdf we")
['12', 'sdf', 'we']
r"\W+"匹配非数字和非字母
re.match(r"\W+"," sf fd").group()非数字和非字母
>>> re.match(r"\W+"," sf fd").group()
' '
>>> re.match(r"\W+"," sf $% @# fd").group()
' '
>>> re.match(r"\W+","$#% sf $% @# fd").group()
'$#% '
量词
R”\w\w”取两个
>>> re.match(r"\w\w","ww we").group()
'ww'
>>> re.match(r"\w\w","12 we").group()
'12'
r"\w{2}"取两个
>>> re.match(r"\w{2}","12 we").group()
'12'
>>> re.match(r"\w{2}","123 we").group()
'12'
>>> re.match(r"\w{2}","1 23 we").group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>> re.match(r"\w{2,4}","1 23 we").group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
r"\w{2,4}",取2到4个,按最多的匹配
>>> re.match(r"\w{2,4}","123 we").group()
'123'
>>> re.match(r"\w{2,4}","12 we").group()
'12'
>>> re.match(r"\w{2,4}","123 we").group()
'123'
>>> re.match(r"\w{2,4}","1235 we").group()
'1235'
>>> re.match(r"\w{2,4}","12435 we").group()
'1243'
>>> re.match(r"\w{5}","12435 we").group()
'12435'
>>> re.match(r"\w{5}","srsdf we").group()
'srsdf'
>>>
r"\w{2,4}?”抑制贪婪性,按最少的匹配
>>> re.match(r"\w{2,4}?","12435 we").group()
'12'
r"\w?"匹配0次和一次,如果没有匹配的,返回空
0次也是匹配了,
>>> re.match(r"\w?","12435 we").group()
'1'
>>> re.match(r"\w?"," 12435 we").group()
''
re.findall(r”\w?”,”12 we”)匹配到最后,没有东西,0次,返回空
>>> re.findall(r"\w?"," 12 we")
['', '1', '2', '', 'w', 'e', '']
re.findall(r"\w"," 12 we")匹配一个
>>> re.findall(r"\w"," 12 we")匹配一个
['1', '2', 'w', 'e']
r"\w*"匹配0次或多次
>>> re.match(r"\w*"," 12435 we").group()
''
>>> re.match(r"\w*","12435 we").group()
'12435'
>>> re.match(r"\w*"," 12435 we")
<_sre.SRE_Match object at 0x0000000002F63ED0>
>>> re.match(r"\w*","12435 we")
<_sre.SRE_Match object at 0x000000000306C030>
>>> re.match(r"\w*","12435 we").group()
'12435'
r"a.b"匹配ab间除回车以外的任意字符
如果想匹配”a.b”,用r"a\.b"
>>> re.match(r"a.b","axb")
<_sre.SRE_Match object at 0x0000000001DCC510>
>>> re.match(r"a.b","a\nb")
>>> re.match(r"a\.b","a.b")
<_sre.SRE_Match object at 0x00000000022BE4A8>
>>> re.match(r"a\.b","axb")
>>> re.match(r".","axb").group()
'a'
>>> re.match(r"a.b","axb").group()
'axb'
练习匹配这个ip地址,规则就是有3个.和4段数,数字从0到255之间,即可
s="i find a ip:1.2.22.123 ! yes"
>>> re.search(r"\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}",s).group()
'1.2.22.123'
re.search(r"(\d{1,3}\.){3}\d{1,3}",s)分组匹配
>>> re.search(r"(\d{1,3}\.){3}\d{1,3}",s).group()
'1.2.22.123'
>>> re.search(r"(\d{1,3}\.){3}\d{1,3}",s).group()
'1.2.22.123
匹配多个字符的相关格式
字符 功能
* 匹配前⼀个字符出现0次或者⽆限次, 即可有可⽆
+ 匹配前⼀个字符出现1次或者⽆限次, 即⾄少有1次
? 匹配前⼀个字符出现1次或者0次, 即要么有1次, 要么没有
{m} 匹配前⼀个字符出现m次
{m,} 匹配前⼀个字符⾄少出现m次
{m,n} 匹配前⼀个字符出现从m到n次
字符 功能
. 匹配任意1个字符(除了\n)
[ ] 匹配[ ]中列举的字符
\d 匹配数字, 即0-9
\D 匹配⾮数字, 即不是数字
\s 匹配空⽩, 即 空格, tab键
\S 匹配⾮空⽩
\w 匹配单词字符, 即a-z、 A-Z、 0-9、 _
\W 匹配⾮单词字符
正则表达式
正则表达式(regular expression)是一个特殊的字符序列,描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串。
将匹配的子串替换或者从某个串中取出符合某个条件的子串,或者是在指定的文章中抓取特定的字符串等。
Python处理正则表达式的模块是re模块,它是Python语言中拥有全部的正则表达式功能的模块。
正则表达式由一些普通字符和一些元字符组成。普通字符包括大小写的字母、数字和打印符号,而元字符是具有特殊含义的字符。
\w+ 只匹配一次,从开头开始匹配
Match,search 的 \w+,都是从开头开始匹配
Findall的\w+是匹配所有的字母
Findall返回的是一个列表
正则表达式大致的匹配过程是:
拿正则表达式依次和字符串或者文本中的字符串做比较,如果每一个字符都匹配,则匹配成功,只要有一个匹配不成功的字符,则匹配不成功。
“.”点可以匹配任何除换行符意外的字符
>>> import re
>>> re.match(r".","1")
<_sre.SRE_Match object at 0x048AFA68>
>>> re.match(r".","1").group()
'1'
>>> re.match(r".","a").group()
'a'
>>> re.match(r"."," ").group()
' '
>>> re.match(r".","!").group()
'!'
>>> re.match(r".","\n").group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>>
匹配反斜杠用re.match(r"\\","\\")
>>> re.match(r"\\","\\").group()
'\\'
"\w"可以匹配下划线
>>> re.match(r"\w","_").group()
'_'
>>> re.match(r"\w+","sad_").group()
'sad_'
>>>
方括号r"[abc]d"匹配,表示开头的字母是方括号中的,后边是d就匹配
>>> re.match(r"[abc]d","ad").group()
'ad'
>>> re.match(r"[abc]d","bd").group()
'bd'
>>> re.match(r"[abc]d","cd").group()
'cd'
>>> re.match(r"[abc]d","d").group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>> re.match(r"[abc]d","gd").group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Attri
尖括号^匹配,r"[^abc]d"非abc的,不能为空
>>> re.match(r"[^abc]d","gd").group()
'gd'
>>> re.match(r"[^abc]d","ad").group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>>
星号 匹配前一个字符0次或多次
"\d"小d匹配数字
>>> re.match(r"\d*","a123").group()
''
>>> re.match(r"\d*","123").group()
'123'
>>> re.match(r"\d*","a123").group()
''
>>> re.match(r"\d*","123").group()
'123'
“\D”大D匹配非数字
>>> re.match(r"\D","a123").group()
'a'
"\D+"匹配非数字1次或多次
>>> re.match(r"\D+","123").group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>> re.match(r"\D+"," 123").group()
' '
>>> re.match(r"\D+","$123").group()
'$'
>>> re.match(r"\D*","%$#123").group()
'%$#'
"\D{2}"匹配非数字2次
>>> re.match(r"\D{2}","%$#123").group()
'%$'
"\D{2,4}匹配非数字2到次,具有贪婪性
>>> re.match(r"\D{2,4}","%$#123").group()
'%$#'
>>> re.match(r"\D{2,4}","%#$#123").group()
'%#$#'
"\D?"问号抑制匹配贪婪性,0次或1次
>>> re.match(r"\D?","%#$#123").group()
'%'
>>>
"\s"小s匹配空白
>>> re.match(r"\s"," \t123").group()
' '
>>> re.match(r"\s"," 123").group()
' '
>>> re.match(r"\s"," 123").group()
'\t'
"\S"大S匹配非空白
>>> re.match(r"\S","a 123").group()
'a'
"\w"小w匹配个位字母或数字或者下划线
>>> re.match(r"\w","sd1a 123").group()
's'
>>> re.match(r"\w","_sd1a 123").group()
'_'
"\w+"匹配1个或多个位字母或数字或者下划线
>>> re.match(r"\w+","_sd1a 123").group()
'_sd1a'
"\W+"大W匹配非字母、数字、下划线
>>> re.match(r"\W+","@#$_sd1a 123").group()
'@#$'
>>> re.match(r"\W","@#$_sd1a 123").group()
'@'
>>>
^abc$匹配开头和结尾,表示字符串就是abc才会匹配
^尖括号在方括号里是非,不在方括号里表示开头匹配
>>> re.search(r"^abc","abc").group()
'abc'
>>> re.search(r"^abc$","abc").group()
'abc'
>>> re.search(r"^abc","abc123").group()
'abc'
>>> re.search(r"^abc$","abc123").group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>> re.search(r"^abc$","abc123").group()
r"^abc.*abc$"开头结尾都是abc,中间是啥都行
>>> re.search(r"^abc.*abc$","abcabc").group()
'abcabc'
>>> re.search(r"^abc.*abc$","abcsdabc").group()
'abcsdabc'
>>> re.search(r"^abc.*abc$","abc@#$sdabc").group()
'abc@#$sdabc'
>>> re.search(r"^abc.*abc$","abc@#_ $sdabc").group()
'abc@#_ $sdabc'
>>> re.match(r"^abc.*abc$","abcabc").group()
'abcabc'
.*表示除回车的任意字符
>>> re.match(r".*","abcabc").group()
'abcabc'
>>> re.match(r".*","abcabc\n").group()
'abcabc'
>>> re.match(r".*","ab\ncabc\n").group()
'ab'
>>
\b匹配字符边界,是空白
>>> re.search(r"\babc\b","23 3abc e3").group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>> re.search(r"\babc\b","23 3 abc e3").group()
'abc'
>>> re.search(r"\babc\b","23 3 abc e3").group()
r"\ba"用\b匹配以a开头的单词
>>> re.findall(r"\ba","ab abv add")
['a', 'a', 'a']
>>> re.findall(r"\ba","ab abv add")
['a', 'a', 'a']
>>> len(re.findall(r"\ba","ab abv add"))
3
>>> re.findall(r"\ba.*","ab abv add")
['ab abv add']
>>> re.findall(r"\ba.*","ab abv add")[0]
'ab abv add'
>>> re.findall(r"\ba.*","ab abv add")[0].split()
['ab', 'abv', 'add']
列出以a开头的单词
可以这样
>>> len(re.findall(r"\ba.*","ab abv add")[0].split())
3
>>>
>>> re.findall(r"\b.*\b","ab abv add")
['ab abv add', '']
>>> re.findall(r"\ba.*\b","ab abv add")
['ab abv add']
>>>
或者这样r"\b[a-zA-Z]*\b"
>>> re.findall(r"\b[a-zA-Z]*\b","ab abv add")
['ab', '', 'abv', '', 'add', '']
>>> re.findall(r"\b[a-zA-Z]+\b","ab abv add")
['ab', 'abv', 'add']
正则表达式编译
Python通过re模块提供对正则表达式的支持。使用re的一般步骤是先将正则表达式的字符串形式编译为pattern实例,然后使用pattern实例处理文本并获取匹配结果(一个Match实例),最后使用Match实例获取信息,进行其他的操作。
编辑正则表达式,可以提高程序的执行速度。下面是pattern模式处理正则表达式的流程:
#coding=utf-8
import re
# 将正则表达式编译成Pattern对象
pattern = re.compile(r'hello')
# 使用Pattern匹配文本,获得匹配结果,无法匹配时将返回None
match = pattern.match('hello world!')
if match:
# 使用Match获得分组信息
print match.group()
c:\Python27\Scripts>python task_test.py
hello
pattern = re.compile(r'hello') pattern.match('hello world!')这两句等价于re.match(r”hello”,”hello world!”)
re.compile(pattern, flags=0) 这个方法是pattern类的工厂方法,目的是将正则表达式pattern编译成pattern对象,并返回该对象。 可以把正则表达式编译成一个正则表达式对象。可以把那些经常使用的正则表达式编译成正则表达式对象,这样可以提高一定的效率。 第二个参数flag是匹配模式,取值可以使用按位或运算符“|”表示同时生效,比如re.I | re.M。当然你也可以在regex字符串中指定模式,比如: re.compile('pattern', re.I | re.M) 它等价于: re.compile('(?im)pattern') flag参数还有一些其他的可选值,之后我们会一一介绍。 re模块提供了很多用于完成正则表达式的功能。那为什么还有使用pattern实例的相应方法替代呢? 使用该pattern模式唯一的好处就是,一处编译,多处复用。
#coding=utf-8
import re
# 将正则表达式编译成Pattern对象
pattern = re.compile(r'hello')
print pattern
# 使用Pattern匹配文本,获得匹配结果,无法匹配时将返回None
match1 = pattern.match('hello world!')
if match1:
print u"第一次使用"
# 使用Match获得分组信息
print match1.group()
match2 = pattern.match("hello, everyone, I am coming.")
if match2 :
print u"第二次使用"
print match2.group()
c:\Python27\Scripts>python task_test.py
<_sre.SRE_Pattern object at 0x04D5B7A0>
第一次使用
hello
第二次使用
hello
pattern对象下有哪些属性和方法:
Pattern对象是一个编译好的正则表达式,也就是通过re.compile()函数编译后得到结果。
通过pattern提供的一系列方法可以对文本进行匹配查找。
Pattern不能直接实例化,必须使用re.compile()函数进行构造。
pattern提供了几个可读属性及方法用于处理正则表达式。
>>> pattern=re.compile(r"hello")
>>> dir(pattern)
['findall', 'finditer', 'flags', 'groupindex', 'groups', 'match', 'pattern', 'scanner', 'search', 'split', 'sub', 'subn']
正则表达式---flags属性
>>> p=re.compile(r"\w",re.DOTALL)
>>> p.flags#这里re.DOTALL就是p的flags属性,不过他的值是16
16
re.match(r".","\n",re.DOTALL)可以匹配换行符
re.DOTALL是模式
>>> re.match(r".","\ne",re.DOTALL).group()
'\n'
>>> re.match(r".*","\ne",re.DOTALL).group()
'\ne'
>>> re.match(r".*","\ne").group()
''
>>>
>>> re.match(r".*","\n").group()
''
>>> re.DOTALL
16
>>> re.match(r".*","\ne",16).group()
'\ne'
re.I模式忽略大小写re.match(r"A","abc",re.I)
>>> re.match(r"A+","abc",re.I).group()
'a'
>>> re.match(r"A.*","abc",re.I).group()
'abc'
分组r"abc(\d+)cde(\d+)"
>>> re.search(r"abc\d+","abc123cde").group()
'abc123'
#分组
>>> re.search(r"abc(\d+)","abc123cde").group()
'abc123'
#group(1)取第一个分组,这里只有一个分组
>>> re.search(r"abc(\d+)","abc123cde").group(1)
'123'
#group(0)打印出所有匹配内容
>>> re.search(r"abc(\d+)","abc123cde").group(0)#
'abc123'
#group(2)取第二个分组内容,这里没有第二个分组,所以报错
>>> re.search(r"abc(\d+)","abc123cde").group(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: no such group
>>>
>>> re.search(r"abc(\d+)cde(\d+)","abc123cde456").group(1)
'123'
>>> re.search(r"abc(\d+)cde(\d+)","abc123cde456").group(2)
'456'
>>> re.search(r"abc(\d+)cde(\d+)","abc123cde456").group()
'abc123cde456'
>>> re.search(r"abc(\d+)cde(\d+)","abc123cde456").group(0)
'abc123cde456'
group(1,2)把1,2两个分组以元组形式取出来
>>> re.search(r"abc(\d+)cde(\d+)","abc123cde456").group(1,2)
('123', '456')
groups()把所有分组都打出来,元组形式
>>> re.search(r"abc(\d+)cde(\d+)","abc123cde456").groups()
('123', '456')
>>> re.search(r"a(\d+)b(\d+)","a123b456").group()
'a123b456'
>>> re.search(r"a(\d+)b(\d+)","a123b456").group(1)
'123'
>>> re.search(r"a(\d+)b(\d+)","a123b456").group(2)
'456'
>>> re.search(r"a(\d+)b(\d+)","a123b456").groups()
('123', '456')
>>> re.search(r"a(\d+)b(\d+)","a123b456").groups()[1]
'456'
>>> re.search(r"a(\d+)b(\d+)","a123b456").groups()[0]
'123'
>>>
分组可以命名
>>> re.search(r"a(\d+)b(\d+)(?P<sign>\w+)","a123b456cde").group('sign')
'cde'
>>> p=re.compile(r"(\w+) (\w+)(?P<sign>.*)",re.DOTALL)
>>> p.match("a b c").group('sign')
' c'
>>>
两个同名命名分组(?P<sign>\d)(?P=sign),表示后边括号引用前边的分组内容,即两处内容一样,但只有前边的是分组。
>>> re.match(r"(?P<sign>\d)(?P=sign)","22").group(1)
'2'
>>> re.match(r"(?P<sign>\d) (?P=sign)","2 2").group(1)
'2'
>>> re.match(r"(?P<sign>\d) (?P=sign)","2 2").groups()
('2',)
>>> re.match(r"(?P<sign>\d) (?P=sign)","2 2").group()
'2 2'
>>> re.match(r"(?P<sign>\d) (?P=sign)","2 2").groups()
('2',)
>>>
命名分组和普通分组
>>> re.match(r"(?P<sign>\d)(\d)","23").group()
'23'
>>> re.match(r"(?P<sign>\d)(\d)","23").groups()
('2', '3')
>>> re.match(r"(?P<sign>\d)(\d)","23").group('sign')
'2'
>>> re.match(r"(?P<sign>\d)(\d)","23").group(2)
'3'
>>> re.match(r"(?P<sign>\d)(\d)","23").group(1)
'2'
>>>
序号引用,和分组命名类似,要和对应的分组匹配的内容必须一样
>>> re.match(r"(\d)(\d)\1","232").group(1)
'2'
>>> re.match(r"(\d)(\d)\1","232").group()
'232'
>>> re.match(r"(\d)(\d)\2","233").group()
'233'
>>> re.match(r"(\d)(\d)\1","232").group()
'232'
>>> re.match(r"(\d)(\d)\2","233").group(2)
'3'
>>> re.match(r"(\d)(\d)\2","233").group(1)
'2'
>>> re.match(r"(\d)(\d)\2","233").groups()
('2', '3')
>>> re.match(r"(\d)7(\d)\2","2733").groups()
('2', '3')
>>> re.match(r"(\d)7(\d)\1","2732").group()
'2732'
>>> re.match(r"(\d)7(\d)\2","2733").group()
'2733'
>>>>>> re.match(r"(\d)(\d)\1","232").group(1)
'2'
>>> re.match(r"(\d)(\d)\1","232").group()
'232'
>>> re.match(r"(\d)(\d)\2","233").group()
'233'
>>> re.match(r"(\d)(\d)\1","232").group()
'232'
>>> re.match(r"(\d)(\d)\2","233").group(2)
'3'
>>> re.match(r"(\d)(\d)\2","233").group(1)
'2'
>>> re.match(r"(\d)(\d)\2","233").groups()
('2', '3')
>>> re.match(r"(\d)7(\d)\2","2733").groups()
('2', '3')
>>> re.match(r"(\d)7(\d)\1","2732").group()
'2732'
>>> re.match(r"(\d)7(\d)\2","2733").group()
'2733'
>>>
正则表达式--groups属性
该属性表示获取表达式中分组的数量。
>>> import re
>>> p=re.compile(r"(\w+)(\w+)(?P<sign>.*)",re.DOTALL)
>>> p.groups
3
>>>
正则表达式--groupindex属性
以表达式中有别名的组的别名为键、以该组对应的编号为值的字典,没有别名的组不包含在内
#coding=utf-8
import re
# 将正则表达式编译成Pattern对象
p = re.compile(r'(\w+) (\w+)(?P<sign>.*)', re.DOTALL)
#获取表达式中所有分组的别名和分组序号组成的字典
print "p.groupindex: ", p.groupindex
c:\Python27\Scripts>python task_test.py
p.groupindex: {'sign': 3}
pattern.match("abc123",3,6)指定在字符串中的匹配范围
>>> pattern=re.compile(r"\d+")
>>> pattern.match("abc123",3,6).group()
'123'
>>> pattern.match("abc1234",3,6).group()
'123'
>>> pattern.match(r"abc123",3,5).group()
'12'
>>> pattern.match(r"abc123234234",3,7).group()
'1232'
>>>
Pattern.search()方法也支持指定范围查询
>>> pattern=re.compile(r"\d+")
>>> pattern.search(r"abc12345",3,6).group()
'123'
正则表达式--findall方法
相比其他方法,finall方法有些特殊。它的作用是查找字符串中所有能匹配的字符串,并以结果存于列表中,然后返回该列表。 这看起来没什么奇怪的,但是奇怪的地方就在于返回的列表中的内容,取决于正则表达式中圆括号的出现情况,也就是分组的情况。如下几种情况:
1.当正则表达式中含有多个圆括号()时,返回列表中的元素由所有满足匹配的内容组成,但是每个元素都是由表达式中所有圆括号匹配的内容组成的元组。而且元组中元素个数与括号对数相同,并且字符串排放顺序跟括号出现的顺序一致(一般看左括号‘ (’就行),字符串内容与每个括号内的正则表达式相对应。
2.当正则表达式中只带有一个圆括号时,返回的列表的元素由所有能成功匹配表达式中圆括号匹配的内容组成,并且该列表中的元素都是字符串,它的内容与括号中的正则表达式相对应。(注意:列表中的字符串只是圆括号中的内容,不是整个正则表达式所匹配的内容。)
3.当正则表达式中没有圆括号时,返回列表中的元素由所有能成功匹配的子串组成。
>>> re.findall(r"((a)b(c))","abc def")
[('abc', 'a', 'c')]
>>> re.findall(r"((a)b(c))","abc abc")
[('abc', 'a', 'c'), ('abc', 'a', 'c')]
>>> re.findall(r"(a)b(c)","abc abc")
[('a', 'c'), ('a', 'c')]
SyntaxError: invalid syntax
>>> re.findall(r"(a)b","abc abc")
['a', 'a']
>>> re.findall(r"(a)b","abc abc")
['a', 'a']
>>> re.findall(r"\d+","1a2b3c")
['1', '2', '3']
>>> re.findall(r"(\d+)(\w)","1a2b3c")
[('1', 'a'), ('2', 'b'), ('3', 'c')]
>>> re.findall(r"((\d+)(\w))","1a2b3c")
[('1a', '1', 'a'), ('2b', '2', 'b'), ('3c', '3', 'c')]
>>> re.findall(r"((\d+)(\w))","11a22b33c")
[('11a', '11', 'a'), ('22b', '22', 'b'), ('33c', '33', 'c')]
>>> re.findall(r"(\d+)(\w)","11a22b33c")
[('11', 'a'), ('22', 'b'), ('33', 'c')]
>>>
正则表达式--pattern.findall方法
函数作用:
该方法的作用是在string[pos, endpos]区间从pos下标处开始查找所有满足pattern的子串,直到endpos位置结束,并以列表的形式返回查找的结果,如果未找到则返回一个空列表。
参数说明:
string:被匹配的字符串
pos:匹配的起始位置,可选,默认为0
endpos:匹配的结束位置,可选,默认为len(string)
也就是说如果不指定pos和endpos这两个参数的话,该方法会在整个字符串中查找所有满足条件的子串。
#coding=utf-8
import re
#找到正则表达式匹配的前10个字母中的所有数字
pattern = re.compile(r'\d+')
result = pattern.findall('o89ne1two2three3four4', 0, 10)
print result
c:\Python27\Scripts>python task_test.py
['89', '1', '2']
>>> import re
>>> pattern=re.compile(r"\d+")
>>> pattern.findall("o89er1ijfj3lsidj4,0,9")
['89', '1', '3', '4', '0', '9']
>>> pattern.findall("o89er1ijfj3lsidj4",0,20)
['89', '1', '3', '4']
>>>
正则表达式re.M,多行匹配
>>> s
'i am a boy\nyou r a girl\ngloryroad'
>>> re.findall(r"\w+",s,re.M)
['i', 'am', 'a', 'boy', 'you', 'r', 'a', 'girl', 'gloryroad']
>>> re.findall(r"\w+$",s,re.M)
['boy', 'girl', 'gloryroad']
多行匹配每行的开头
>>> s
'i am a boy\nyou r a girl\ngloryroad'
>>> re.findall(r"^\w+",s,re.M)
['i', 'you', 'gloryroad']
正则表达式--finditer方法
finditer函数跟findall函数一样,匹配字符串中所有满足的子串,只是返回的是一个迭代器,而不是一个像findall函数那样的存有所有结果的list,这个迭代器里面存的是每一个结果的一个匹配对象,这样可以节省空间,一般用在需要匹配大量的结果时,类似于range和xrange的区别。
函数作用:
匹配字符串string中所有满足的字串,只是返回的是一个迭代器,而不是一个像findall函数那样存有所有结果的list,这个迭代器里面存的是每一个结果的一个匹配对象,这样可以节省空间,一般用在需要匹配大量的结果时,类似于range和xrange的区别。
参数说明:
pattern:匹配的正则表达式
string:被分割的字符串
flags:标志位,用于控制正则表达式的匹配方式。如是否区分大小写、是否多行匹配等。
>>> s
'i am a boy\nyou r a girl\ngloryroad'
>>> for i in re.finditer(r"\w+",s,re.M):
... print i.group()
...
i
am
a
boy
you
r
a
girl
gloryroad
>>> for i in re.finditer(r"[A-Za-z]+","one12two34three56four"):
... print i.group()
...
one
two
three
four
__________________________________________________________________________________________________________________________________
正则表达式—pattern.split 方法,re.split方法
函数作用:
分割字符串,将字符串string用给定的正则表达式匹配的字符串进行分割,并返回分割后的结果list。
参数说明:
string:被匹配的字符串
maxsplit:用于指定最大分割次数,可选,默认为0,表示全部分割。
#coding=utf-8
#用数字分割
import re
p=re.compile(r"\d+")
#不指定分割次数
resList=p.split("one1two2three3four4")
print resList
#只分割两次
print p.split("one1two2three3fout4",2)
c:\Python27\Scripts>python task_test.py
['one', 'two', 'three', 'four', '']
['one', 'two', 'three3fout4']
>>> p=re.compile(r"\d+")
>>> print p.split("one1two2three3four4")
['one', 'two', 'three', 'four', '']
>>> print p.split("one1two2three3four4",2)
['one', 'two', 'three3four4']
>>> re.split(r"\d+","a1b2c3d")
['a', 'b', 'c', 'd']
>>> re.split(r"\d+","a1b2c3d",2)
['a', 'b', 'c3d']
>>> re.split(r"\d+","a1b2c3d",1)
['a', 'b2c3d']
Re.split()可以加模式
>>> re.split(r"[a-z]","a1B2c3d",2,re.I)
['', '1', '2c3d']
>>> re.split(r"[a-z]","a1B2c3d",4,re.I)
['', '1', '2', '3', '']
正则表达式—sub方法
函数作用:
使用repl替换string中每一个匹配的子串后返回替换后的字符串。
当repl是一个字符串时,可以使用\id或\g<id>、\g<name>引用分组,但不能使用编号0。
当repl是一个方法时,它必须传一个Match对象,并必须返回一个字符串用于替换(返回的字符串中不能再引用分组)。
pattern.sub(repl, string[, count = 0])
参数说明:
repl:用于替换的字符串
string:要被替换的字符串
count:替换的次数,如果为0表示替换所有匹配到的字串,如果是1表示替换1次,为2替换2次等,该参数必须是非负整数,默认为0。
>>> import re
>>> re.sub(r"ab","123","ab ab cd")
'123 123 cd'
>>> re.sub(r"[a-zA-Z]","1","aZ aM cd")
'11 11 11'
>>>
指定替换次数
>>> re.sub(r"[a-zA-Z]","1","aZ aM cd",2)
'11 aM cd'
>>> re.sub(r"[a-zA-Z]","1","aZ aM cd",count=2)
'11 aM cd'
>>> re.sub(r"[a-zA-Z]","1","aZ aM cd",3)
'11 1M cd'
>>> re.sub(r"[a-zA-Z]","1","aZ aM cd",4)
'11 11 cd'
Subn返回替换次数
>>> re.subn(r"[a-zA-Z]","1","aZ aM cd")
('11 11 11', 6)
带加号
>>> re.subn(r"[a-zA-Z]+","1","aZ aM cd")
('1 1 1', 3)
repl为方法时
#encoding=utf-8
import re
p=re.compile(r"(\w+) (\w+)")
s="i say,hello world!!!"
#\2,\1表示分组引用,分别代表第二个分组,第一个分组
print p.sub(r"\2 \1",s)
#rep1为方法时,将匹配的结果m传入方法
def func(m):
print "m.groups():",m.groups()
print "group1:",m.group(1)
print "group2:",m.group(2)
return m.group(1).title() + " " + m.group(2).title()
print p.sub(func,s)#就是用p.match(s)的结果作为参数传给func函数执行
c:\Python27\Scripts>python task_test.py
say i,world hello!!!
m.groups(): ('i', 'say')
group1: i
group2: say
m.groups(): ('hello', 'world')
group1: hello
group2: world
I Say,Hello World!!!
>>> print re.sub(r"(\w+) (\w+)",r"\2 \1","i say,hello world!")
say i,world hello!
等价于下边
>>> s
'i say, hello world!'
>>> p=re.compile(r"(\w+) (\w+)")
>>> print p.sub(r"\2 \1",s)
say i, world hello!
"i say,hello word"
一共替换2次:
第一次替换:i say--->分组1:i 分组2:say \2 \1--->say i
say i,hello world
第二次替换:hello word
hello world--->分组1:hello 分组2:world \2 \1--->word hello
函数作为sub()的第二个参数re.sub(r"\d+",multiply,"10 20 30 40 50")
#encoding=utf-8
import re
def multiply(m):
print m.group()
#将分组0的值转成整型
v=int(m.group(0))
#将分组0的整型值乘以2,然后返回
return str(v*2)
#使用multiply方法作为sub第二个参数,将匹配到的每个数字作为参数传入multiply函数
#处理后将返回结果替换为相应字符串
result=re.sub(r"\d+",multiply,"10 20 30 40 50")
print result
c:\Python27\Scripts>python task_test.py
10
20
30
40
50
20 40 60 80 100
Group(0)返回所有匹配结果
Pos表示从第几个字符开始匹配的
Endpos表示从第几个字符结束匹配的
开区间
String尝试匹配的字符串
>>> import re
>>> re.search(r"\d+","ab12cd").group()
'12'
>>> re.search(r"\d+","ab12cd").pos
0
>>> re.search(r"\d+","ab12cd").endpos
6
>>> re.search(r"\d+","ab12cd").string
'ab12cd'
Lastindex表示最后一个分组是分组中的第几个
>>> re.search(r"(?P<hi>\d+)","ab12cd").lastindex
1
>>> re.search(r"(?P<hi>\d+)(cd)","ab12cd").lastindex
2
>>> re.search(r"(?P<hi>\d+)(cd)","ab12cd").groups()
('12', 'cd')
Lastgroup最后一个分组如果有别名,则返回别名,否则返回空
>>> re.search(r"(?P<hi>\d+)(cd)","ab12cd").lastgroup
>>> re.search(r"(?P<hi>\d+)","ab12cd").lastgroup
'hi'
Expand()函数
将匹配到的分组代入template中然后返回。template中可以使用\id或\g<id>、\g<name>引用分组,但不能使用编号0。\id与\g<id>是等价的;但\10将被认为是第10个分组,如果你想表达\1之后是字符'0',只能使用\g<1>0。
#coding=utf-8
import re
m=re.search(r"(\w+)! (\w+) (\w+)","HMan! gloryroad train")
print m.group()
#将匹配的结果带入
print m.expand(r"result:\3 \2 \1")
expand(template)
c:\Python27\Scripts>python task_test.py
HMan! gloryroad train
result:train gloryroad HMan
groupdict([default=None])获取分组的名字
该函数的作用是,将所有匹配到并且指定了别名的分组,以别名为key,匹配到的字串为value,存于字典中,然后返回这个字典。如果表达式中未设置别名分组,就会返回一个空字典。
'' #coding=utf-8
import re
line="This is the last one"
res=re.match(r"(?P<group1>.*) is (?P<group2>.*?).*",line,re.M|re.I)
print "res.group():",res.groups()
groupDict=res.groupdict()
if groupDict:
print groupDict
else:
print "无别名分组"
c:\Python27\Scripts>python task_test.py
res.group(): ('This', '')
{'group1': 'This', 'group2': ''}
>>> re.match(r".*","asdf").group()
'asdf'
>>> re.match(r".*?","asdf").group()
?抑制正则贪婪型,?
?要放在量次后边,*.
>>> re.search(r"\d+","abc1234e e").group()
'1234'
>>> re.search(r"\d+?","abc1234e e").group()
'1'
Search匹配多行,第一行匹配到了,就不匹配第二行了
#coding=utf-8
import re
#search从第一行开始匹配,如果第一行匹配到了,就不再匹配了
#如果是findall就会匹配到三行
p=re.compile(r"^.*[a-z]+$",re.I|re.M)
string= """
You r a beautiful girl
Right"""
matchResult=p.search(string)
print matchResult.group()
if matchResult:
print matchResult.group()
else:
print "no string found!"
c:\Python27\Scripts>python task_test.py
You r a beautiful girl
You r a beautiful girl
Findall
>>> re.findall(r"^.*[a-z]+$","i am boy\nyou r girl",re.I|re.M)
['i am boy', 'you r girl']
>>> re.findall(r"^.*[a-z]+$","i am boy\n you r girl",re.I|re.M)
['i am boy', ' you r girl']
>>> re.findall(r"^.*[a-z]+$"," i am boy\n you r girl",re.I|re.M)
[' i am boy', ' you r girl']
#coding=utf-8
import re
p = re.compile(r'^.*[a-z]+$', re.I|re.M)
string = """I am a Boy
Your a beautiful Girl
Right"""
matchResult = p.findall(string)
if matchResult:
print matchResult
else:
print "no string found"
c:\Python27\Scripts>python task_test.py
['I am a Boy', ' Your a beautiful Girl', ' Right']
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
正则表达式-修饰符注释
正则表达式可以包含一些可选标志修饰符来控制匹配模式。修饰符被指定为一个可选的标志,用在正则表达式处理函数中的flag参数中。多个标志可以通过使用按位或运算符“|“来指定它们,表示同时生效。如:
re.I | re.M被设置成I和M标志,
#coding=utf-8
import re
a=re.compile(r"""\d+ #匹配至少一个连续的数字,自定义注释
\. #匹配点(.)
\d* #匹配数字至少0个""",re.X)
b=re.compile(r"\d+\.\d*")#a和b则正则表达式等价的
print "a.search('test12.58 2.0 abc 3.8'):"
print a.search("test12.58 2.0 abc 3.8").group()
print "b.search('test12.58 2.0 abc 3.8'):"
print b.search("test12.58 2.0 abc 3.8").group()
c:\Python27\Scripts>python task_test.py
a.search('test12.58 2.0 abc 3.8'):
12.58
b.search('test12.58 2.0 abc 3.8'):
12.58
正则表达式—前向肯定断言与后向肯定断言
前向肯定断言的语法:
(?<=pattern)
前向肯定断言表示你希望匹配的字符串前面是pattern匹配的内容时,才匹配。
后向肯定断言的语法:
(?=pattern)
后向肯定断言表示你希望匹配的字符串的后面是pattern匹配的内容时,才匹配。
所以从上面的介绍来看,如果在一次匹配过程中,需要同时用到前向肯定断言和后向肯定断言时,那你必须将前向肯定断言表达式写在要匹配的正则表达式的前面,而后向肯定断言表达式写在你要匹配的字符串的后面,表示后向肯定模式之后,前向肯定模式之前。
获取C语言代码中的注释内容
你希望找出c语言的注释中的内容,它们是包含在’/*’和’*/’之间,不过你并不希望匹配的结果把’/*’和’*/’也包括进来,那么你可以这样用:
前向肯定断言括号中的正则表达式必须是能确定长度的正则表达式,比如\w{3},而不能写成\w*或者\w+或者\w?等这种不能确定个数的正则模式符。
前向肯定r"(?<=abc)\d+"
r"(?<=abc)\d+"只有字符串前边是abc开头的才匹配后边的
>>> re.search(r"(?<=abc)\d+","abc123")
<_sre.SRE_Match object at 0x0000000002A7A510>
>>> re.search(r"(?<=abc)\d+","abc123").group()
'123'
>>> re.search(r"(?<=[abc])\d+","ab3c123").group()
'3'
>>> re.search(r"(?<=[abc])\d+","abc123").group()
'123'
>>> re.search(r"(?<=[abc])\d+","ab3c123").group()
'3'
>>> re.search(r"(?<=abc)\d+","abc123").group()
'123'
>>> re.search(r"(?<=abc)\d+","1abc123").group()
'123'
>>> re.search(r"(?<=abc)\d+","1abc1233q").group()
'1233'
>>> re.search(r"(?<=[abc])\d+","1abc123").group()
'123'
>>> re.search(r"(?<=[abc])\d+","1ab123").group()
'123'
>>> re.search(r"(?<=[abc])\d+","1c123").group()
'123'
>>> re.search(r"(?<=[abc])\d+","1123").group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>>
后向肯定r"(\d+(?=abc))"
>>> re.search(r"(\d+(?=abc))","1123abc").group()
'1123'
正则表达式—前向否定断言与后向否定断言
前向否定断言的语法:
(?<!pattern)
前向否定断言表示你希望匹配的字符串的前面不是pattern匹配的内容时,才匹配。
后向否定断言的语法:
(?!pattern)
后向否定断言表示你希望匹配的字符串后面不是pattern匹配的内容时,才匹配。
前向否定,r"(?<!abc)\d+",前边不是abc才匹配
?是固定写法
>>> re.search(r"(\d+(?=abc))","1123abc").group()
'1123'
>>> re.search(r"(?<!abc)\d+","abc1").group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>> re.search(r"(?<!abc)\d+","ab2c1").group()
'2'
>>> re.search(r"(?<!abc)\d+","ab2234c1").group()
'2234'
>>>
后向否定,r"(\d+(?!abc))",后边不是abc,才匹配
>>> re.search(r"(\d+(?!abc))","1dd").group()
'1'
>>> re.search(r"(\d+(?!abc))","1abc").group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>> re.search(r"(\d+(?!abc))","112abc").group()
'11'
>>>
肯定和否定总结
前向肯定:表示在前面(?<=pattern)匹配的内容存在,它后面的正则才生效
(?<=pattern)正则的内容
re.search(r"(?<=[abc])\d+","abc123")
后向肯定:表示在后面(?=pattern)匹配的内容存在,它前面的正则才生
正则的内容(?=pattern)
re.search(r"(\d+(?=abc))","123abc")
前向否定:表示在前面(?<!pattern)匹配的内容不存在,它后面的正则才生效
(?<!pattern)正则的内容
re.search(r"(?<!abc)\d+","ab1c1")
后向否定:表示在后面(?!pattern)匹配的内容不存在,它前面的正则才生
正则的内容(?!pattern)
re.search(r"(\d+(?!abc))","1dd")