Python大道至简(第七部分)
作者:下家山(qq:1209050967,微信:xiajiashan)
Python高级
二:Python正则表达式
2.1 什么是正则
正则其实是regulation的意思,即规则。
那表达式又是什么意思呢?
2.2 什么是表达式
这里的表达式是指一个字符串;
所以综合来讲,正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
2.3 什么是规则的字符串
我举个例子大家就明白了,比如在《The Old Man and the Sea》这本短篇小说里面(老人与海),我们要搜索一个字符串,你就不能搜”@#341892”这样的字符串,因为在这本小说里面,凭你的直觉不应该有这样的字符串,那么“@#341892”就不是一个规则字符串。
2.4 python正则表达式的重要性
Python中的正则表达式在很多需要字符串搜索的应用中是非常重要的,比如著名的爬虫工具,各类搜索类网站,对正则表达式的应用无不尽其级。
http://www.cnblogs.com/tina-python/p/5508402.html
http://blog.csdn.net/kelvinmao/article/details/51485774
http://www.jb51.net/article/34642.htm 讲了什么是r(raw)
http://blog.sina.com.cn/s/blog_a15aa56901017liq.html
http://blog.csdn.net/kelvinmao/article/details/51485774
2.5 re模块
Python自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。
re 模块使 Python 语言拥有全部的正则表达式功能。
compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。
re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。
本章节主要介绍Python中常用的正则表达式处理函数。
2.6 re.match函数
函数语法:
re.match(pattern,string, flags=0)
函数参数说明:
参数 | 描述 |
pattern | 匹配的正则表达式 |
string | 要匹配的字符串。 |
flags | 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。 |
2.7 re.match实例
Match的意思如下:
如果以匹配这个意思去理解re.match,感觉很不好理解(我个人认为,不知你有没有同感)。但是,如果用“比较”去理解代码,似乎容易一些,符合我的习惯。
比如第4行,print(re.match('hello','hello'))
是用第一个字符串’hello’和第二个字符串’hello’进行比较,在默认情况下,re.match这个函数是从第0个位置开始进行比较的,即先拿第一个字符串的第一个字符,与第二个字符串的第一个字符进行比较,如果相等,则进行第2个字符的比较,这样一直比较到最后一个字符串。
如果第一个字符就比较失败,那么根本不会比较第二个。
那么如果是这种情况呢:
第一个字符不同,比较失败。
2.8 re.match的第三个参数flag
那么大小写如何区分呢?
大小写是敏感的。
如果第三个参数flags=2,那么表示大小写忽略,此时match为目标字符串。
多行匹配的情况
目标字符串换行了,也可以匹配。
但是,当flags=4的时候,多行匹配失败。
2.9 关于模式pattern
怎么理解re.match(pattern,string, flags=0)的第一个参数?
Pattern是模式的意思。
那么在re.match的应用中,怎么理解呢,hello这个字符串是一个什么模式呢?
其实,“hello”这种字符串也是一个模式,只不过这个模式是非常简单的,所以我们感觉不出来。当我们使用了模式通配符的时候,就能体现模式的强大作用了。我们来看实例。
这里的点“.”表示任意字符,此时体现了模式的概念。
2.10 各种元字符
下面列出python中模式匹配中常用到的通配符。
模式 | 描述 |
^ | 匹配字符串的开头 |
$ | 匹配到字符串的末尾。 |
. | 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。 |
[...] | 用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k' |
[^...] | 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。 |
re* | 匹配0个或多个的表达式。 |
re+ | 匹配1个或多个的表达式。 |
re? | 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式 |
re{ n} |
|
re{ n,} | 精确匹配n个前面表达式。 |
re{ n, m} | 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式 |
a| b | 匹配a或b |
(re) | G匹配括号内的表达式,也表示一个组 |
(?imx) | 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。 |
(?-imx) | 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。 |
(?: re) | 类似 (...), 但是不表示一个组 |
(?imx: re) | 在括号中使用i, m, 或 x 可选标志 |
(?-imx: re) | 在括号中不使用i, m, 或 x 可选标志 |
(?#...) | 注释. |
(?= re) | 前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。 |
(?! re) | 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功 |
(?> re) | 匹配的独立模式,省去回溯。 |
\w | 匹配字母数字及下划线 |
\W | 匹配非字母数字及下划线 |
\s | 匹配任意空白字符,等价于 [\t\n\r\f]. |
\S | 匹配任意非空字符 |
\d | 匹配任意数字,等价于 [0-9]. |
\D | 匹配任意非数字 |
\A | 匹配字符串开始 |
\Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。c |
\z | 匹配字符串结束 |
\G | 匹配最后匹配完成的位置。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 |
\B | 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 |
\n, \t, 等. | 匹配一个换行符。匹配一个制表符。等 |
\1...\9 | 匹配第n个分组的内容。 |
\10 | 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。 |
正则表达式实例
字符匹配
实例 | 描述 |
python | 匹配 "python". |
字符类
实例 | 描述 |
[Pp]ython | 匹配 "Python" 或 "python" |
rub[ye] | 匹配 "ruby" 或 "rube" |
[aeiou] | 匹配中括号内的任意一个字母 |
[0-9] | 匹配任何数字。类似于 [0123456789] |
[a-z] | 匹配任何小写字母 |
[A-Z] | 匹配任何大写字母 |
[a-zA-Z0-9] | 匹配任何字母及数字 |
[^aeiou] | 除了aeiou字母以外的所有字符 |
[^0-9] | 匹配除了数字外的字符 |
特殊字符类
实例 | 描述 |
. | 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。 |
\d | 匹配一个数字字符。等价于 [0-9]。 |
\D | 匹配一个非数字字符。等价于 [^0-9]。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 |
\w | 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。 |
\W | 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。 |
对于前一个字符”l”重复4次。
以上实验各位可以自行实验。
2.11 关于group方法
我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。
匹配对象方法 | 描述 |
group(num=0) | 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。 |
groups() | 返回一个包含所有小组字符串的元组,从 1 到所含的小组号。 |
注意1:在(.*)中,.表示任意字符,*表示对前一个字符重复0到无数次。
注意2:括号一定要,python就是通过()来分组的。
2.12 re.search函数
re.search 扫描整个字符串并返回第一个成功的匹配。
函数语法:
re.search(pattern, string, flags=0)
函数参数说明:
参数 | 描述 |
pattern | 匹配的正则表达式 |
string | 要匹配的字符串。 |
flags | 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。 |
匹配成功re.search方法返回一个匹配的对象,否则返回None。
实例
注意1:为什么不匹配第一个数字2367呢?
因为,2367只有4个数字,而我们的正则表达式要求5个数字。
注意2:为什么最后一个数字23456没有搜索出来呢?
因为,这是re.search这个函数决定的,此函数只返回第一个结果,后续不再查找。
2.13 span方法
Span这个单词本身的意思是:
在这里取跨度的意思,就是所找到的字符串在原字符串里面的位置
2.14 re.findall函数
re.findall(pattern, string[, flags])
以list的形式返回string中所有与pattern匹配的不重叠的字符串。String从左向右扫描,匹配的返回结果也是以这个顺序。
2.15 re.mach re.search re.findall的区别
共同点:语法一样
re.match(pattern,string[, flags=0])
re.search(pattern, string[, flags=0])
re.findall(pattern, string[, flags=0])
不同点1:
Re.match返回一个对象
Re.search返回一个对象
Re.findall返回一个列表
不同点2:
Re.match总是从字符串“开头”去匹配,并返回匹配的字符串的match对象。
Re.search扫描整个字符串并返回第一个成功的匹配。
Re.findall扫描整个字符串并以列表返回成功匹配的所有字符串。
2.16 re.sub
Python 的 re 模块提供了re.sub用于替换字符串中的匹配项。
语法:
re.sub(pattern, repl,string, count=0, flags=0)
参数:
· pattern : 正则中的模式字符串。
· repl : 替换的字符串,也可为一个函数。
· string : 要被查找替换的原始字符串。
· count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
注意:这里是通过Len这个函数检查出字符串后面还多了一个空格的。
2.17 re.subn返回替换结果及次数
返回的是一个元组,包括替换结果和次数。
格式:
subn(pattern,repl, string, count=0, flags=0)
2.18 关于多行匹配re.M
re.M是多行匹配的意思,通常作为re.match,re.search,re.compile的参数使用。
http://blog.sina.com.cn/s/blog_6acdaf6d01014t3r.html
2.19 作业
需要资料:营业执照正本,副本,公章,所有投资人身份证复印件各一份。
快递地址:上海松江区泗泾镇古楼公路1218弄132号1704室,同润山河小城。
张为同:13917584958收。
上面是我微信上收到的一串信息,当我去顺丰寄快递的时候,顺丰的微信公众号可以智能匹配我的地址信息,你只需要把这个字符串拷贝进他的智能匹配窗口,它就能帮你过滤出地址和电话号码。
请你写一个程序实现之。
注意:第8行,[\s\S]*,这里不能使用.*,因为.是匹配除了换行以外的字符。
而\s是匹配任意空白字符,\S是匹配任意非空白字符。这样\s\S连在一起就是所有字符了。这里还可以使用\w\W,\d\D。还可以使用re.S【见2.8】
接下来的问题
1:怎么处理收件人地址后面有两个冒号,你还要考虑中文冒号和英文冒号,还要考虑别人微信里面的原始字符串里面是逗号情况。
2:怎么处理同润山河小城
3:怎么处理收件人地址后面还有手机号信息
接下来的问题:怎么过滤掉冒号?
此时,用户有可能用的是中文冒号,英文冒号,也有可能是逗号
2.20 re.compile函数
编译正则表达式模式,返回一个对象的模式。(可以把那些常用的正则表达式编译成正则表达式对象,这样可以提高一点效率。)
格式:
re.compile(pattern,flags=0)
pattern: 编译时用的表达式字符串。
flags 编译标志位,用于修改正则表达式的匹配方式,如:是否区分大小写,多行匹配等。
例程:
注意:\w表示匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
2.21 Re.compile的好处
Re.compile很多人觉得没什么有用的地方,其实他的好处是在你写了一个比较大的程序的时候你才会去思考,有没有一种方法,可以方便保存模式,不用每次都去敲那些奇怪的,难以记住的模式字符。
在下面这个程序里面,如果再要去找str字符串中包含oo的单词,你又要去写一次匹配模式”\woo\w”,在几千行的项目里面,有时候模式会很长,此时,compile就非要有用了。我们可以编译出很多的匹配模式,方便后续使用。从而简化程序代码量。
2.22re.finditer搜索迭代器
搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器。找到 RE 匹配的所有子串,并把它们作为一个迭代器返回。
格式:
re.finditer(pattern,string, flags=0)
2.23 re.split字符串分割
按照能够匹配的子串将string分割后返回列表。
可以使用re.split来分割字符串,如:re.split(r'\s+', text);将字符串按空格分割成一个单词列表。
格式:
re.split(pattern, string[,maxsplit])
maxsplit用于指定最大分割次数,不指定将全部分割。
实例解析:
2.24 (非)贪婪匹配和惰性匹配
贪婪匹配是匹配所有的,非贪婪匹配就是匹配部分,惰性匹配与非贪婪匹配是一个意思。
*+?都是贪婪匹配,即尽可能匹配,?如果放在前面就是贪婪匹配,放在后面则变成惰性匹配。
实例1:
实例2:
注意:要把(.*)理解成H1>title<H1,或者说要把“H1>title<H1”理解成一个整体。
实例3:
这是因为:如果前后均有限定条件的时候,就不存在什么贪婪模式了,非匹配模式失效。
2.25 ()括号的作用
我们在上一节中,不知大家是否有一个疑问:在输出结果中,为什么不含有a和b字母呢?
其实,这是python中的括号的问题。
如果有括号,则只匹配括号里面的表达式。
我们来看一个实例:
三:网络编程
Python提供了两个模块(两种级别)访问的网络程序实现。:
· 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法。Socket模块既可以做服务器开发,也可以做客户端开发。
· 高级别的网络服务模块 SocketServer,它提供了服务器中心类,可以简化网络服务器的开发。
SocketServer,只能用于服务器开发。
3.1.什么是socket
套接字是一种通信机制,凭借这种机制,服务器/客户系统的开发工作可以在本地单机上进行,也可以在网络上进行。
套接字很明确的将客户和服务器区分开来。而且,套接字可以实现多个客户连接到一个服务器。
3.2 socket()函数
Python 中,我们用 socket()函数来创建套接字,语法格式如下:
socket.socket([domain[, type[, proto]]])
参数
· domain: 域的意思,这里的域是指互联网的区域,有:
常用AF_UNIX或者AF_INET。
· type: 套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAM
或SOCK_DGRAM
· protocol: 一般不填默认为0.
待续.....
四:python调试方法
4.1断点调试
https://blog.csdn.net/IMBA123456789/article/details/42046165
N回车执行下一条