正则表达式模块 re
参考:http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html1、两种模式python中有两种正则表达式,上面一种是未编译模式,直接使用re模块中的函数。编译使用方法未编译模式>>> import re >>> re_string="{ {(.*?)}}">>> some_string="this is a string with { {word}} embedded in { {curly brackets}} to show an { {example}} of { {regular expression}}“>>> for match in re.findall(re_string,some_string):#findall找出所有匹配的数据放到一个列表里... print "MATCH->",match... MATCH-> wordMATCH-> curly bracketsMATCH-> exampleMATCH-> regular expression已编译模式>>> import re >>>obj=re.compile("{ {(.*?)}}")>>> some_string="this is a string with { {word}} embedded in { {curly brackets}} to show an { {example}} of { {regular expression}}">>> for match in obj.findall(some_string): ... print "MATCH->",match ... MATCH-> wordMATCH-> curly bracketsMATCH-> exampleMATCH-> regular expression2、re.compile创建一个模式的对象re.compile创建一个模式的对象,最常使用的正则表达式方法,里面建立多个匹配模式3、re.findall() 全文搜索匹配搜索字符串中指定模式的所有匹配。其匹配模式返回的数据结构类型将取决于模式是否定义了一个组,如果没有在正则表达式模式中定义组,但却找到匹配。将返回一个字符串列表。如果定义了组(也就是定义了多个模式),并且其中有匹配,那么re.findall()返回一个多元列表(列表中的数据是多个元组)re.finditer() re.finditer()对re.findall()稍微修改,不同之处是返回一个迭代。每一次迭代的元素都是一个正则表达式匹配的对象m=re.compile(r".")>> m_match=m.findall(text) #findall找出所有匹配的数据放到一个列表里>>> print m_match['T', 'h', 'e', ' ', 'A', 't', 't', 'i', 'l', 'a', ' ', 't', 'h', 'e', ' ', 'H', 'u', 'n', ' ', 'S', 'h', 'o', 'w']多模式>>> m=re.compile(r'(.)(\w+)(\s+)') >>> m_match=m.findall(text)>>> print m_match[('T', 'he', ' '), ('A', 'ttila', ' '), ('t', 'he', ' '), ('H', 'un', ' ')]4、找到首次匹配re.match()re.search()re.match()和re.search()这两个方法提供相似的功能,他们对字符串应用一个正则表达式,定义开始搜索(pos)和结束搜索的位置(endpos),并且都返回一个【首次匹配】指定模式的匹配对象。参数pos是一个索引. re.search(re_string,pos=1,endpos=3)这两个工具不仅可以显示一个模式是否匹配一段文本,而且可以返回一个match()对象.match()对象包含当你搜索文本时各种各样的数据片段,start(),end(),span(),group(),groups()和groupdict()都是match()方法。match()方法介绍start():匹配行开始位置 end():配行结束位置 span():配置行的长度(包含空格),group(): 匹配的内容 group()和group(0)一样。group(1)可能是匹配的多个模式中第一个,group(2)第2个groups(): 将多个模式匹配中匹配出来的元素构成元组('local2:80',),groupdict(): 返回一个命名组字典。匹配的别名作为key,匹配的数据作为valuevhost_start=re.compile(r'<VirtualHost\s+(.*?)>')vhost_end=re.compile(r'</VirtualHost')docroot_re=re.compile(r'( DocumentRoot\s+)(\S+)')print "vhost_start_match.span is:",vhost_start_match.span()print "vhost_start_match.start is:",vhost_start_match.start()print "vhost_start_match.end is:",vhost_start_match.end()print "vhost_start_match.group is:",vhost_start_match.group()print "vhost_start_match.groups is:",vhost_start_match.groups()print "vhost_start_match.groupdict is:",vhost_start_match.groupdict()print "vhost_start_match.groups 0 is :",vhost_start_match.groups()[0]#print "vhost_start_match.groups 1 is :",vhost_start_match.groups()[1]print "vhost_start_match.group 0 is :",vhost_start_match.group()[0]print "vhost_start_match.group 1 is :",vhost_start_match.group()[1]对应结果vhost_start_match.span is: (0, 23)vhost_start_match.start is: 0vhost_start_match.end is: 23vhost_start_match.group is: <VirtualHost local2:80>vhost_start_match.groups is: ('local2:80',)vhost_start_match.groupdict is: {}vhost_start_match.groups 0 is : local2:80vhost_start_match.group 0 is : <vhost_start_match.group 1 is : V 5、正则模块的拆分和替换re.split() re.sub()re.split() : 正则模块中的拆分re.sub() : 正则模块中的替换1)拆分split(string[, maxsplit]) | re.split(pattern, string[, maxsplit]):split(pattern, string, maxsplit=0, flags=0)#按照能够匹配的子串将string分割后返回列表。maxsplit用于指定最大分割次数,(1是两个)不指定将全部分割。 >>> import re>>> p=re.compile(r'\d+') >>> print p.split('one1two2three3four4') ['one', 'two', 'three', 'four', '']上面是编译模式,下面是非编译模式>>> lines='one1two2three3four4'>>> re.split(r'\d+',lines) ['one', 'two', 'three', 'four', '']>>> re.split(r'\d+',lines)[0]'one'>>> re.split(r'\d+',lines,2)['one', 'two', 'three3four4']#(模式 字符串)最大拆分个数默认为0为最大 \s+一个或多个空白,\d+一个或多个数字>>> re.split(r'\s+',lines[0]) ['HTTP/1.1', '301', 'Moved', 'Permanently']>>> re.split(r'\s+',lines[0],1)['HTTP/1.1', '301 Moved Permanently']>>> re.split(r'\s+',lines[0],4)['HTTP/1.1', '301', 'Moved', 'Permanently'] #超过最大也显示最大2)替换sub(repl, string[, count]) | re.sub(pattern, repl, string[, count]):使用repl替换string中每一个匹配的子串后返回替换后的字符串。当repl是一个字符串时,可以使用\id或\g<id>、\g<name>引用分组,但不能使用编号0。当repl是一个方法时,这个方法应当只接受一个参数(Match对象),并返回一个字符串用于替换(返回的字符串中不能再引用分组)。count用于指定最多替换次数,不指定时全部替换 >>> p = re.compile(r'(\w+) (\w+)')>>> s = 'i say, hello world!'>>> print p.sub(r'\2 \1', s)say i, world hello!docroot_re=re.compile(r'(DocumentRoot\s+)(\S+)')sub_line=docroot_re.sub(r'\1%s' % newdocroot,line)编译性用r'\1%s' % newdocroot替换line匹配的字符串\1%s 替换第2个分组,正则分组2个,1为第二个,也就是DocumentRoot空白后面的非空白字符串<1>.替换所有匹配的子串#用newstring替换subject中所有与正则表达式regex匹配的子串result = re.sub(regex, newstring, subject)<2>.替换所有匹配的子串(使用正则表达式对象)reobj = re.compile(regex)result = reobj.sub(newstring, subject)6、正则编译的研究>>> m=re.compile(r".") >>> m_match=m.search(text) #对的首次匹配指定模式的匹配对象>>> print m_match <_sre.SRE_Match object at 0x28495b80>['__class__', '__copy__', '__deepcopy__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'end', 'endpos', 'expand', 'group', 'groupdict', 'groups', 'lastgroup', 'lastindex', 'pos', 're', 'regs', 'span', 'start', 'string']>>> m_match.group() 'T'>>> m_match.groups()()>>> m_match=m.findall(text) #findall找出所有匹配的数据放到一个列表里>>> print m_match['T', 'h', 'e', ' ', 'A', 't', 't', 'i', 'l', 'a', ' ', 't', 'h', 'e', ' ', 'H', 'u', 'n', ' ', 'S', 'h', 'o', 'w']7、模式分组log_line_re=re.compile(r'(?P<remote_host>\S+)\s+\S+\s+\S+\s+\[[^\[\]]+\]\s+"[^"]+"\s+(?P<status>\d+)\s+(?P<bytes_sent>-|\d+)\s*')\s+空白 \S+字符串 >>> m=re.compile(r'(.)(\w+)') >>> m_match=m.search(text) >>> m_match.group() #匹配的内容'The'>>> m_match.group(1) #多个模式中匹配第一个模式的内容,这里匹配(.)'T'>>> m_match.group(2) #多个模式中匹配第二个模式的内容,这里匹配(\w+)'he'>>> m_match.groups() #将多个模式匹配中匹配出来的元素构成元组('T', 'he')>>> m_match.groups(1) #这里面的数字目前没什么意义('T', 'he')>>> m_match.groups()[0] #取出第一个匹配模式首次匹配的内容和m_match.group(1)一样'T'>>> m_match.groups()[1]'he多匹配一个空格看看>>> m=re.compile(r'(.)(\w+)(\s+)') >>> m_match=m.search(text) >>> m_match.group() 'The '>>> m_match.group(0)'The '>>> m_match.group(1)'T'>>> m_match.group(3)' '>>> m_match.groups() ('T', 'he', ' ')>>> m_match.groups()[2] 'he'8、groupdict() 研究返回一个命名组字典#!/usr/bin/evn pythonimport sysimport relog_line_re=re.compile(r'(?P<remote_host>\S+)\s+\S+\s+\S+\s+\[[^\[\]]+\]\s+"[^"]+"\s+(?P<status>\d+)\s+(?P<bytes_sent>-|\d+)\s*')def formatlogline(logfile):
for line in logfile: m=log_line_re.match(line) groupdict=m.groupdict() print groupdict if __name__=='__main__': if not len(sys.argv) > 1: sys.exit(1) infile_name=sys.argv[1] try: infile=open(infile_name,'r') except IOError: print "infile_name not found!" print __doc__ sys.exit(1) else: formatlogline(infile) infile.close()python logtest.py /var/log/httpd-access.log获取到数据的格式{'status': '404', 'remote_host': '192.168.1.1', 'bytes_sent': '209'}{'status': '200', 'remote_host': '192.168.1.1', 'bytes_sent': '44'}{'status': '200', 'remote_host': '192.168.1.1', 'bytes_sent': '44'}{'status': '200', 'remote_host': '192.168.1.200', 'bytes_sent': '44'}{'status': '200', 'remote_host': '192.168.1.200', 'bytes_sent': '44'}{'status': '200', 'remote_host': '192.168.1.200', 'bytes_sent': '44'}编译的模式匹配里设置了多个匹配模式(?P<remote_host>\S+),(?P<status>\d+),(?P<bytes_sent>-|\d+)(?P<name>...) 分组,除了原有的编号外再指定一个额外的别名EG:(?P<id>abc){2} 结果abcabc,有一个别名id;m.groupdict()方法后{'id':'abcabc'}(?P<bytes_sent>-|\d+):匹配|左右两边任意一个