python 学习笔记day09-pythonz正则表达式、socket模块

RE模块

核心函数和方法

match函数

尝试用正则表达式模式从字符串的开头匹配,如果匹配成功,则返回一个匹配对象,否则返回None

>>> re.match(‘foo‘,‘food‘)   #在food 搜索foo
             <_sre.SRE_Match object at 0xb70babb8>
            >>> m = re.match(‘foo‘,‘food‘)
            >>> m.group()
            ‘foo‘
            >>> m = re.match(‘foo‘,‘seafood‘)   # 在seafood中匹配foo,匹配不到,因为match是从开头开始匹配
            >>> print m
            None

search函数

在字符串中查找正则表达式模式的第一次出现,如果匹配成功,则返回一个匹配对象否则返回Non

>>> m = re.search(‘foo‘,‘seafood‘) # 在seafood中匹配foo,search在字符串中匹配。
            >>> m.group()
            ‘foo‘

group函数

使用match或search匹配成功后,返回的匹配对象可以使用group方法获得匹配内容

findall

>>> m = re.search(‘foo‘,‘seafood is food.‘)
            >>> m.group()
            ‘foo‘
            >>> re.findall(‘foo‘,‘seafood is food.‘)
            [‘foo‘, ‘foo‘]
        finditer

>>> re.finditer(‘foo‘,‘seafood is food.‘)
            <callable-iterator object at 0xb70be62c>
            >>> m = re.finditer(‘foo‘,‘seafood is food.‘)
            >>> for i in m:
            ...   print i.group()
            ...
            foo
            foo
        compile函数

对正则表达式模式进行编译,返回一个正则表达式对象

不是必须使用这种方式,但是在大量匹配情况下,可以提升效率

>>> import re
            >>> patt = re.compile(‘foo‘)
            >>> m = patt.match(‘food‘)
            >>> print m.group()
            foo

split方法

根据正则表达式中的分隔符把字符串分隔为一个列表,并返回匹配成功的列表

字符串也有

>>> mylist = re.split(‘\.|-‘,‘hell-world.data‘)   #使用‘.‘和‘-’作为字符串的分隔符
            >>> print mylist
            [‘hell‘, ‘world‘, ‘data‘]

sub方法

把字符串中所有匹配正则表达式的地方替换成新的字符串

>>> import re
            >>> re.sub(‘X‘,‘Mr. Smith‘,‘Hi X, Nice to see you X.‘)
            ‘Hi Mr. Smith, Nice to see you Mr. Smith.‘
        groups

>>> import re

>>> m = re.search("(tom)orrow","I will see you tomorrow.")
            >>> m.group()
            ‘tomorrow‘
            >>> m.groups()
            (‘tom‘,)
            >>> m.groups(1)
            (‘tom‘,)

>>> m = re.search("(tom)or(row)","I will see you tomorrow.")
>>> m.group()
‘tomorrow‘
>>> m.groups()
(‘tom‘, ‘row‘)
>>> m.groups(1)
(‘tom‘, ‘row‘)
>>> m.groups(2)
(‘tom‘, ‘row‘)
>>> m.group(1)
‘tom‘
>>> m.group(2)
‘row‘

注意分组情况

>>> m = re.search(‘((b(c))d)e‘,‘abcdef‘)
            >>> m.group()
            ‘bcde‘
            >>> m.group(1)
            ‘bcd‘
            >>> m.group(2)
            ‘bc‘
            >>> m.group(3)
            ‘c‘

正则表达式

匹配单个字符

说明
. 匹配任意字符,换行符除外
[...x-y...] 匹配字符组里的任意字符
[^...x-y...] 匹配不再字符组里的任意字符
\d 匹配任意数字,与[0-9]同义
\D 匹配非数字
\w 匹配任意数字字母下划线,与[0-9a-aA-Z_]同义
\W \w的反,匹配非数字字母下划线
\s 匹配空白字符,与[\r\v\f\t\n]同义
\S \s的反,匹配非空格字符

匹配一组字符

符号 说明
literal 匹配字符串的值
re1|re2 匹配正则表达式re1或re2
* 匹配前面出现的正则表达式零次或多次
+ 匹配前面出现的正则表达式一次或多次
匹配前面出现的正则表达式零次或一次
{M,N} 匹配前面出现的正则表达式至少M次最多N次

其他元字符

符号 说明
^ 匹配字符串的开头
$ 匹配字符串的结尾
\b
匹配单词的边界

echo "tom tomorrow" | grep ‘\btom\b‘

() 对正则表达式分组
\nn 匹配已保存的分组

贪婪匹配

*、+和?都是贪婪匹配操作符,在其后加上?可以取消其贪婪匹配行为

正则表达式匹配对象通过groups函数获取子组

>>> import re
            >>> data = ‘My phone number is:15088889999‘
            >>> m = re.search(‘.+(\d+)‘,data)
            >>> print m.groups()
            (‘9‘,)
            >>> m = re.search(‘.+?(\d+)‘,data)
            >>> m.groups()
            (‘15088889999‘,)
分析apache访问日志

编写一个apache

1、统计每个客户端访问apache服务的次数

2、将统计信息通过字典的方式显示出来

3、分别统计客户端是Firefox和MSI的访问次数

4、分别使用函数式编程和面向对象编程的方式实现

#!/usr/bin/env python
# coding: utf8

import re

def count_patt(fname,patt):
    patt_dict = {}
    cpatt = re.compile(patt)
    with open(‘fname‘) as fobj:
        for line in fobj:
            m = cpatt.search(line)
            if m:
                key = m.group()
                ‘‘‘if key not in patt_dict:
                    patt_dict[key] = 1
                else:
                    patt_dict[key] +=1‘‘‘
                # 如果key不在字典中,值为1,否则值加1.
                patt_dict[key] = patt_dict.get(key,0) + 1
                return patt_dict

def sort(adict):
    alist = []
    patt_list = addict.items()
    for i in range(len(patt_list)):
        greater = patt_list[0]
        for j in range(len(patt_list[1:])):
            ‘‘‘if greater[1] < patt_list[j + 1][1]:
                greater = patt_list[j + 1]‘‘‘
            greater = greater if greater[1] > = patt_list[j + 1][1] else patt_list[j + 1]
        alist.append(greater)
        patt_list.remove(greater)
        return alist

if __name__ == ‘__main__‘:
    log_file = ‘/var/log/httpd/access.log‘
    ip_patt =‘^(\d+\.){3}\d+‘
    br_patt = ‘Firefox|MSIE‘
    print count_patt(log_file,ip_patt)
    print count_patt(log_file,br_patt)
    ip_count = count_patt(log_file,ip_patt)
    print ip_count
    print sort(ip_count)

>>> import tab
>>> import collections
>>> c = collections.Counter()
>>> c
Counter()
>>> c.update(‘abc‘)
>>> c
Counter({‘a‘: 1, ‘c‘: 1, ‘b‘: 1})
>>> c.update(‘ab‘)
>>> c
Counter({‘a‘: 2, ‘b‘: 2, ‘c‘: 1})
>>> c.update(‘a‘)
>>> c
Counter({‘a‘: 3, ‘b‘: 2, ‘c‘: 1})
>>> c = collections.Counter()
>>> c.update((‘192.168.1.1‘,))
>>> c
Counter({‘192.168.1.1‘: 1})
>>> c.update((‘192.168.1.3‘,))
>>> c.update((‘192.168.1.34‘,))
>>> c
Counter({‘192.168.1.3‘: 1, ‘192.168.1.34‘: 1, ‘192.168.1.1‘: 1})
>>> c.update((‘192.168.1.34‘,))
>>> c.update((‘192.168.1.34‘,))
>>> c
Counter({‘192.168.1.34‘: 3, ‘192.168.1.3‘: 1, ‘192.168.1.1‘: 1})
>>> c.most_common(1)
[(‘192.168.1.34‘, 3)]
>>> c.most_common(2)
[(‘192.168.1.34‘, 3), (‘192.168.1.3‘, 1)]

#!/usr/bin/env python
#coding; utf8

import re
import collections
class CountPatt(object):
    def __init__(self,patt):
        self.cpatt = re.compile(patt)
    def count_patt(self,fname):
        c = collections.count()
        with open(fname) as fobj:
            for line in fobj:
                m = self.cpatt.search(line)
                if m:
                    c.update(m.group())
        return c

if __name__ == ‘__main__‘:
    log_file = ‘/var/log/httpd/access.log‘
    ip_patt =‘^(\d+\.){3}\d+‘
    br_patt = ‘Firefox|MSIE‘
    c1 = CountPatt(ip_patt)
    print c1.count_patt(log_file)
    print c1.count_patt(log_file).most_common(2)
    c2 = CountPatt(br_patt)
    print c2.count_patt(log_file)
    print c2.count_patt(log_file).most_common(2)

socket模块

技术

C/S B/S Peer to Peer

地域

LAN / WAN / MAN

安全

intranet / /extranet/internet

c/s架构

什么是C/S架构

服务器是一个软件或硬件,用于提供客户需要的“服务”

硬件上,客户端常见的就是平时所使用的pc机,服务器常见的有联想、DELL等厂商生产的各种系列服务器

软件上,服务器提供的服务主要是程序的运行,数据的发送与接受、合并、升级或其它的程序或数据的操作

套接字

套接字是一种具有“通讯端点”概念的计算机网络数据结构

套接字起源于20世纪70年代,加利福尼亚大学伯克利分校版本的Unix

一种套接字是Unix套接字,其“家族名”为AF_UNIX

另一种套接字十基于网络的,“家族名”为AF_INET

如果把套接字比作电话的插口,那么主机与端口就像区号与电话号码的一对组合

面向连接和无连接

无论是哪一种地址家族,套接字的类型只有两种。一种是面向连接的,一种是无连接的套接字

无连接的主要协议十用户数据包协议(UDP),套接字类型为SOCK_DGRAM

python中使用socket模块中的socket函数实现套接字的创建

socket函数与方法

创建TCP服务器

创建Tcp服务器的主要步骤如下:

1、创建服务器套接字: s = sockets.socket()

2、绑定地址到套接字: s.bind()

3、启动监听:s.listen()

4、接受客户连接: s.accept()

5、与客户端通信:recv()/send()

6、关闭套接字:s.close()

tcpsrv.py

#!/usr/bin/env python
#coding:utf8

import socket

host = ‘‘  #指定该服务运行的地址,空字符串表示:0.0.0.0
port = 12345  #端口号必须是整数(int)类型
addr = (host,port)
#创建套接字socket(模块名).socket(模块内方法)(socket.AF_INET(地址家族),socket.SOCK_STREAM(套接字类型,TCP用STREAM表示))
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#程序默认行为:比如程序默认使用了一个端口,当程序结束了,该套接字/端口会被系统保留一分钟。
#为了避免这样的情况(端口/套接字不被占用),设置套接字的选项
#SOL_SOCKET套接字本身
#SO_REUSEADDR,是否允许重用地址,1表示允许,一般服务器端会设置这个选项
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

#绑定IP 和端口号
s.bind(addr)
#监听
#listen里面接受一个数值,很多系统支持到5
s.listen(1)
#accept返回一个元组,客户机的套接字,客户机的地址,记住一个阻塞的概念
cli_sock,cli_addr = s.accept()
print "Got connetion from : ",cli_addr
#从客户机接收数据存到data中
data = cli_sock.recv(4096)
print data
#向客户端发送数据
cli_sock.send("I C U!\n")
#关闭客户端套接字
cli_sock.close()
#关闭服务器端的套接字
s.close()

测试:

1终端

# python tcpsrv.py

2终端

# netstat -ntpl | grep 12345

# telnet Ip  12345

创建TCP时间戳服务器

编写一个tcp服务器

1.服务器监听在0.0.0.0的12345 的端口上

2.收到客户端数据后,将其加上时间戳后返回给客户端

3.如果客户端发过来的字符全是空白字符,则终止与客户端的连接

#!/usr/bin/env python
#coding: utf8
import socket
import time

host = ‘‘   #0.0.0.0
port = 12345

addr = (host,port)

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(addr)
s.listen(1)

while True:
    cli_sock,cli_addr = s.accept()
    print "Got connection from :", cli_addr
    while True:
        data = cli_sock.recv(4096)
        if not data.strip():
            break
        print data
        cli_sock.send("[%s] %s" % (time.ctime(),data))
    cli_sock.close()
s.close()

创建TCP客户端

创建TCP客户端的步骤主要如下:

1、创建客户端套接字:cs = socket.socket()

2、尝试连接服务器:cs.connect()

3、与服务器通信:cs.send()/cs.recv()

4、关闭客户端套接字:cs.close()

#!/usr/bin/env python
#coding: utf8
import socket

host = ‘172.40.3.217‘  # 要连接的服务器的IP
port = 12345 #要连接服务器的端口
addr = (host,port)
#创建套接字,家族是AF_INET,类型是SOCK_STREAM
c = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#连接服务器
c.connect(addr)

while True:
    data = raw_input(‘> ‘)
    if not data:
        break
    c.send(data)  #将数据发送给服务器
    print c.recv(4096)

c.close()

WEB.py

#!/usr/bin/env python

import socket

host = ‘‘
port = 80
addr = (host,port)

with open(‘/var/www/html/index.html‘) as fobj:
    contents = fobj.read()

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(addr)
s.listen(1)

while True:
    cli_sock,cli_addr = s.accept()
    cli_sock.send(contents)
    cli_sock.close()

s.close()

创建UDP服务器

创建UDP服务器的主要步骤如下:

1、创建服务器套接字: s = socket.socket()

2、绑定服务器套接字:s.bind()

3、接收、发送数据:s.recvfrom()/s.sendto()

4、关闭套接字:s.close()

创建UDP时间戳服务器

编写一个UDP服务器

1 、服务器监听在0.0.0.0的12345端口

2、r接收客户端数据后,将其加上时间戳后回送给客户端

#!/usr/bin/env python
#coding: utf8
import  socket
import time

host = ‘‘
port = 12345
addr = (host,port)

# 创建套接字。家族AF_INET,类型:SOCK_DGRAM
s =  socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#保证程序退出之后可以立即运行
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(addr)

while True:
    data,cli_addr = s.recvfrom(4096)  #recvfrom 返回发送方的数据和地址
    #收到的数据在发挥给发送方,数据,目的地地址
    s.sendto("[%s] %s" % (time.ctime(),data),cli_addr)
#关闭套接字
s.close()

创建UDP客户端

创建UDP客户端的步骤主要如下:

1.创建客户端套接字:cs = socketsocket()

2.与服务器通信: cs.sendto()/cs.recvfrom()

3.关闭客户端套接字: cs.close()

#!/usr/bin/env python
#coding: utf8

import socket
import sys

host = sys.argv[1]
port = int(sys.argv[2])
addr = (host,port)

c = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

while True:
    data = raw_input(‘> ‘)
    if not data:
        break
    c.sendto(data,addr)  #发送给addr服务器的数据。
    print c.recvfrom(4096) #输出接受到的数据,默认返回数据,服务器地址,服务器端口

print c.recvfrom(4096)[0]

c.close()

时间: 2024-10-11 01:23:50

python 学习笔记day09-pythonz正则表达式、socket模块的相关文章

python 学习笔记 14 -- 常用的时间模块之datetime

书接上文,前面我们讲到<常用的时间模块之time>,这次我们学习datetime -- 日期和时间值管理模块 使用apihelper 查看datetime 模块,我们可以看到简单的几项: date       ---  日期对象,结构为date(year, month, day) time       ---  时间值对象,结构为 time([hour[, minute[, second[, microsecond[, tzinfo]]]]]).时间对象所有的参数都是可选的.tzinfo 可以

python 学习笔记 13 -- 常用的时间模块之time

Python 没有包含对应日期和时间的内置类型,不过提供了3个相应的模块,可以采用多种表示管理日期和时间值: *    time 模块由底层C库提供与时间相关的函数.它包含一些函数用于获取时钟时间和处理器的运行时间,还提供了基本解析和字符串格式化工具 *    datetime 模块为日期.时间以及日期时间值提供一个更高层接口.datetime 中的类支持算术.比较和时区配置. *    calendar 模块可以创建周.月和年的格式化表示.它还可以用来计算重复事件.给定日期是星期几,以及其他基

python学习笔记-Day05-第二部分(模块简介)

模块是一种组织形式,他是 实现了某个功能的代码的集合,它将彼此有关系的代码组织到一个文件或一个目录中(目录中包含多个文件,这里改称为 "包"). 模块分三类 内置模块 第三方模块 自定义模块 模块的定义: package/└── mod01.py package/├── mod01.py├── mod02.py└── mod03.py package/├── __init__.py├── mod01.py├── mod02.py└── mod03.py package/├── __in

Python学习笔记4(函数与模块)

1.Python程序的结构 Python的程序由包(package).模块(module)和函数组成. 模块是处理一类问题的集合,由函数和类组成. 包是由一系列模块组成的集合.包是一个完成特定任务的工具箱. 2.函数 2.1函数的定义 def sayHello(): print 'Hello World!' # block belonging to the function sayHello() 2.2函数的参数Python中任何东西都是对象,所以参数只支持引用传递的方式.Python通过名称绑

python学习笔记(基础四:模块初识、pyc和PyCodeObject是什么)

一.模块初识(一) 模块,也叫库.库有标准库第三方库. 注意事项:文件名不能和导入的模块名相同 1. sys模块 import sys print(sys.path) #打印环境变量 print(sys.argv) #打印相对路径,在pycharm输出结果是绝对路径,因为在pycharm中调用 print(sys.argv[2]) #可以从数据列表中取值,[2]指取第三位.        标准库存放位置:C:\Python35\Lib 第三方库存放位置C:\Python35\Lib\site-p

python学习笔记九:正则表达式

本文不涉及正则表达式本身的内容,只记一下python中正则的用法及常用方法. 一.re模块 python中用re模块进行正则处理 >>>import re >>>s = r'abc' >>>re.findall(s,'aaaabcaaaaa') ['abc'] 或先编译(会更快): >>> import re >>> r1 = re.compile(r'abc', re.I) >>> re.find

python学习笔记9:正则表达式

一.简介 正则表达式就是用来查找字符串的:用来匹配一些比较复杂的字符串. 使用正确表达式需要引入re模块        (regular定期的有规律的) 二.匹配字符串的方法 三.常用的正则表达式符号

Python学习笔记总结(二)函数和模块

一.函数 函数的作用:可以计算出一个返回值,最大化代码重用,最小化代码冗余,流程的分解. 1.函数相关的语句和表达式 语句        例子 Calls        myfunc(‘diege','eggs',meat=‘lit’) #使用函数 def,return,yield      def adder(a,b=1,*c):                        return a+b+c[0] global        changer():                 gl

python学习笔记21(正则表达式)

正则表达式模式: 除了控制字符(+ ? . * ^ $ ( ) [ ] { } | \),所有字符匹配自己.可以通过用反斜杠前就转义控制字符. 下表列出了Python中可用正则表达式语法: 模式 描述 ^ 匹配的开始的 $ 匹配行尾 . 匹配除换行符的任何单个字符.使用-m选项允许其匹配换行符也是如此. [...] 匹配括号内任何单个字符 [^...] 匹配任何单个字符不在括号中 re* 匹配0个或多个匹配前面表达式. re+ 匹配1个或多个先前出现的表达式. re? 匹配0或1前面出现的表达式

python学习笔记系列----(四)模块

这一章主要是叙述了python模块的概念以及包的概念,还有它们的使用:收获也是大大的. 提起python文件,经常会听到3个名词,python脚本,python模块,python包.脚本的概念是从python交互式命令行引用过来的,把在命令行内运行的代码段复制到一个文件里再运行,这个文件就可以称为一个脚本:脚本之间可能存在相同的函数等,为了一个脚本能使用另一个脚本里的函数等,这里的另一个脚本就可以称为一个模块,也就是说一个模块里的定义是可以被导入到别的模块或者主模块中使用的:python包是py