python模块整理14-re模版
正则表达式模块 re
参考:http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html
1、两种模式
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-> word
MATCH-> curly brackets
MATCH-> example
MATCH-> 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-> word
MATCH-> curly brackets
MATCH-> example
MATCH-> regular expression
2、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,匹配的数据作为value
vhost_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: 0
vhost_start_match.end is: 23
vhost_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:80
vhost_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 python
import sys
import re
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*')
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+):匹配|左右两边任意一个