python-10


核心笔记:查找与匹配的比较
本章通篇涉及到对查找和匹配用法的讲述。当我们完全讨论与字符串中模式有关的正则表达式
时,我们会用术语“matching”(“匹配”),指的是术语attern-matching(模式匹配)。在Python
专门术语中,有两种主要方法完成模式匹配:搜索(searching)和匹配(matching)。搜索,即在字符
串任意部分中查找匹配的模式,而匹配是指,判断一个字符串能否从起始处全部或部分的匹配某个
模式。搜索通过earch()函数或方法来实现,而匹配是以调用match()函数或方法实现的。
总之,当我们说模式的时候,我们全部使用术语“matching”(“匹配”);我们按照Python 如
何完成模式匹配的方式来区分“搜索”和“匹配”。

 任意字符是.*    前面的字符0到多次
 
 
 
 
 
  1. >>> import re
  2. >>> m = re.match('foo', 'foo abc')
  3. >>> m
  4. <_sre.SRE_Match object at 0x7f5e25904718>
  5. >>> m.group()
  6. 'foo'
  7. >>> m = re.match('foo', 'abc foo')
  8. >>> m
  9. >>> print m
  10. None
核心笔记: RE 编译(何时应该使用compile 函数?)
在第十四章,我们曾说过Python 的代码最终会被编译为字节码,然后才被解释器执行。我们特
别提到用调用eval() 或 exec()调用一个代码对象而不是一个字符串,在性能上会有明显地提升,
这是因为对前者来说, 编译过程不必执行。换句话说,使用预编译代码对象要比使用字符串快,因
为解释器在执行字符串形式的代码前必须先把它编译成代码对象。
这个概念也适用于正则表达式,在模式匹配之前,正则表达式模式必须先被编译成regex 对象。
由于正则表达式在执行过程中被多次用于比较,我们强烈建议先对它做预编译,而且,既然正则表
达式的编译是必须的,那使用么预先编译来提升执行性能无疑是明智之举。re.compile() 就是用来
提供此功能的。
其实模块函数会对已编译对象进行缓存,所以不是所有使用相同正则表达式模式的search()和
match()都需要编译。即使这样,你仍然节省了查询缓存,和用相同的字符串反复调用函数的性能开
销。 在Python1.5.2 版本里, 缓存区可以容纳20 个已编译的正则表达式对象,而在1.6 版本里,
由于另外添加了对Unicode 的支持,编译引擎的速度变慢了一些,所以缓存区被扩展到可以容纳100
个已编译的regex 对象。

  1. >>> import re
  2. >>> bt = 'bat|bet|bit'            正则表达式模式:bat,bet,bit
  3. >>> m = re.match(bt, 'bat')            #'bat'是匹配的
  4. >>> if m is not None: m.group()
  5. ...
  6. 'bat'
  7. >>> m = re.match(bt, 'blt')        没有匹配'blt'模式
  8. >>> if m is not None: m.group()
  9. ...
  10. >>>
  11. >>> m = re.match(bt, 'He bit me!')        不匹配字符串
  12. >>> if m is not None: m.group()
  13. ...
  14. >>>
  15. >>> m = re.search(bt, 'He bit me!')    搜索到'bit'
  16. >>> if m is not None: m.group()
  17. ...
  18. 'bit'

以下的例子中,我们将说明点号是不能匹配换行符或非字符(即,空字符串)的:
  1. >>> anyend = '.end'
  2. >>> m = re.match(anyend, 'bend')            点号匹配'b'
  3. >>> if m is not None: m.group()
  4. ...
  5. 'bend'
  6. >>> m = re.match(anyend, '\nend')        匹配字符(\n除外)
  7. >>> if m is not None: m.group()
  8. ...
  9. >>> m = re.search('.end', 'The end.')        匹配' '
  10. >>> if m is not None: m.group()
  11. ...
  12. ' end'
下面的例子是来搜索一个真正点号(小数点)的正则表达式,在正则表达式中,用反斜线对它进
行转义,使点号失去它的特殊意义:
  1. >>> patt314 = '3.14'
  2. >>> pi_patt = '3\.14'
  3. >>> m = re.match(pi_patt, '3.14')        完全匹配
  4. >>> if m is not None: m.group()
  5. ...
  6. '3.14'
  7. >>> m = re.match(patt314, '3014')            点号匹配'0'
  8. >>> if m is not None: m.group()
  9. ...
  10. '3014'
  11. >>> m = re.match(patt314, '3.14')        点号匹配'.'
  12. >>> if m is not None: m.group()
  13. ...
  14. '3.14'

 
 
 
 
 
 
 
 
 
  1. #!/usr/bin/env python
  2. import random
  3. import string
  4. import time
  5. import sys
  6. doms = ('com', 'edu', 'net', 'org', 'gov')
  7. for i in range(random.randint(5, 10)):
  8. dtint = random.randint(0, 1733720368)
  9. dtstr = time.ctime(dtint)
  10. shorter = random.randint(4, 7)
  11. em = ''
  12. for j in range(shorter):
  13. em += random.choice(string.lowercase)
  14. longer = random.randint(shorter, 12)
  15. dn = ''
  16. for j in range(longer):
  17. dn += random.choice(string.lowercase)
  18. print '%s::%s@%s.%s::%d-%d-%d' % (dtstr, em, dn, random.choice(doms), dtint, shorter, longer)
 
贪婪匹配

  1. >>> mydata = 'fdsfla^&*1234'
  2. >>> mypatt = '.*(\d)'
  3. >>> import re
  4. >>> m = re.search(mypatt, mydata)
  5. >>> m.group()
  6. 'fdsfla^&*1234'
  7. >>> m.group(1)
  8. '4'
  9. >>> mypatt = '.*?(\d)'
  10. >>> m = re.search(mypatt, mydata)
  11. >>> m.group()
  12. 'fdsfla^&*1'
  13. >>> m.group(1)
  14. '1'
统计一个文件中出现IP的次数,以字典的方式打印
1、用函数式编程的方式
  1. #!/usr/bin/env python
  2. import re
  3. import sys
  4. def countPatt(patt, fname):
  5. db = {}
  6. with file(fname) as f:
  7. for i in f:
  8. m = re.search(patt, i)
  9. if m is not None:
  10. dbkey = m.group()
  11. db[dbkey] = db.get(dbkey, 0) + 1
  12. return db
  13. def test():
  14. ip_patt = '^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'
  15. print countPatt(ip_patt, sys.argv[1])
  16. ie_patt = 'Firefox|MSIE|Chrome|curl'
  17. print countPatt(ie_patt, sys.argv[1])
  18. bash_patt = 'bash$|nolgoin$'
  19. print countPatt(bash_patt, sys.argv[1])
  20. if __name__ == '__main__':
  21. test()
 改
  1. #!/usr/bin/env python
  2. import re
  3. import sys
  4. class Counts(object):
  5. def __init__(self, patt):
  6. self.patt = patt
  7. self.db = {}
  8. def countPatt(self, fname):
  9. with file(fname) as f:
  10. for i in f:
  11. m = re.search(self.patt, i)
  12. if m is not None:
  13. dbkey = m.group()
  14. self.db[dbkey] = self.db.get(dbkey, 0) + 1
  15. return self.db
  16. def test():
  17. countip = Counts('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
  18. print countip.countPatt(sys.argv[1])
  19. countbrowser = Counts('curl|Chrome')
  20. print countbrowser.countPatt(sys.argv[1])
  21. if __name__ == '__main__':
  22. test()
 
利用socket模块编写简单的TCP服务器。该服务器接受用户数据,加上时间发送给客户端

  1. #!/usr/bin/env python
  2. import socket
  3. import time
  4. host = ''
  5. port = 54321
  6. addr = (host, port)
  7. tcps = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  8. tcps.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  9. tcps.bind(addr)
  10. tcps.listen(5)
  11. print 'server startd ... ... \n\t waiting client..'
  12. while True:
  13. try:
  14. tcpCliSock, addr = tcps.accept()
  15. except KeyboardInterrupt:
  16. break
  17. print 'Welcome: ', addr
  18. while True:
  19. data = tcpCliSock.recv(4096).strip()
  20. if len(data) == 0:
  21. tcpCliSock.close()
  22. break
  23. print data
  24. tcpCliSock.send('[%s] %s\n' % (time.ctime(), data))
  25. tcps.close()

 
 




posted @ 2016-12-19 14:27  Final233  阅读(284)  评论(0编辑  收藏  举报