一个完整的正则使用过程

#调用re模块:

In [11]: import re

# re.match(pattern, string)第一个参数是你正则的规则, 第二个参数是检测的字符串:

In [12]: a=re.match(r"redhat","redhathello")

In [13]: print a.group()  
redhat

#re.match尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回None:

In [14]: a=re.match(r"redhat","helloredhat")

In [16]: print a
None

# 如果没有找到匹配, 也返回None:

In [17]: a=re.match(r"redhat","hellolinux")

In [18]: print a
None

正则表达式(re=regular expression)

\d和\D

In [2]: a=re.match(r"\d","1234")In [3]: print a.group()
1In [5]: a=re.match(r"\D","he1234")In [6]: print a.group()
h

\s和\S 

In [9]: a=re.match(r"\s","\th123")In [10]: print a.group()#这里不是什么都没有返回,其实是返回了/t,一个table键的长度的空行

In [11]: a=re.match(r"\S","\t")In [12]: print a
None

 \w和\W

In [17]: a=re.match(r"\w","_h1")In [18]: print a.group()
_In [19]: a=re.match(r"\W","*#_h1")In [20]: print a.group()
*

 [ ]

根据[ ]的特性,下面这些都可以是等价的:

[0123456789] = \d = [0-9]
[^0123456789] = \D = [^0-9]
[a-zA-Z0-9_] = \w
[^a-zA-Z0-9_] = \W
[\n\t\r] = \s
[^\n\t\r] = \S

*

#代表a字符出现0次或多次

#match方法结果实际是函数,所以如果返回一个函数也能说明匹配成功了,如下就是成功匹配字符a在" "字符串中出现0次或多次

In [67]: re.match(r"a*","hello")
Out[67]: <_sre.SRE_Match at 0xfe6098>
In [68]: re.match(r"a*"," ")
Out[68]: <_sre.SRE_Match at 0xfca920>

+

#代表a字符至少出现1次

In [72]: print re.match(r"a+","hello")
None
In [75]: print re.match(r"a+","aahello")
<_sre.SRE_Match object at 0xfcad98>

练习1:匹配电话号码

需求:区号010-七位数字,中间“-”可以省略

#coding:utf-8
import re
reg=r"010-?\d{7}$"
#匹配010开头的,-可以出现1次或0次,单个数字出现7次并以这7位数字结尾
phones=["010-1234567", "0101234567", "010123","010-a123333"]
for i in phones:a=re.match(reg,i)if a:print "%s 合法" %(a.group())else:print "%s 不合法" %(i)
#group方法只会打印出符和条件的内容,因此这里直接打印列表中的元素

执行结果:

练习2:匹配字符串

需求::匹配出字符串第一个字母为大写字母, 后面都是小写字母, 并且这些小写字母可有可无

#coding:utf-8
import re
s=["hello","Hello","hAlla","H","a"]
reg=r"[A-Z][a-z]*"
for i in s:a=re.match(reg,i)if a:print "%s 合法" %(i)else:print "%s 不合法" %(i)

执行结果:

练习3:匹配qq邮箱

找出列表中符和条件的邮箱地址, 并存储到/tmp/mail.txt文件中;
邮箱地址以@qq.com结尾;
@qq.com前面的内容由字母,数字或者下划线组成, 但至少4位, 最多20位

#coding:utf-8
import re
s=["dsadsad@qq.com","123@qq.com","qwer@qq.com","zsdcf@11.com"]
def ismail_ok(x):reg=r"\w{4,20}@qq.com$"a=re.match(reg,i)if a:return Trueelse:return False
mail=[i+"\n" for i in s if ismail_ok(i)]
#使用列表生成式,如果符合条件就输出列表中的元素加上回车字符
with open("/tmp/mail.txt","a+") as f:f.writelines(mail)
#由于mial列表中的元素已经自带换行了,所以这里直接用列表写入mail.txt文件中的每个元素是会自动换行的

执行结果:

|

In [5]: a=re.match(r"redhat|hello","hellohdjfhhhawreda")
In [6]: print a.group()
hello
In [9]: a=re.match(r"redhat|hello","redhathdjfhhhawreda")
In [10]: print a.group()
redhat

练习4:

匹配出0-100之间的数字, 包括1和100

#coding:utf-8
import re
s=["0","1","2","45","37","100","199","897","0.7","ab"]
reg=r"^0$|^100$|[1-9]\d?$"
#匹配0,匹配100,匹配以1-9开头任意数字结尾的
for i in s:a=re.match(reg,i)if a:print "%s 合法" %(i)else:print "%s 不合法" %(i)

执行结果:

groups()方法

groups以元组方式返回符合条件的分组

In [25]: a=re.match(r"(\w{4,20})@(qq.com)$","abcd@qq.com")    #这里多加了两对括号,表示元组里的内容

In [26]: a.groups()
Out[26]: ('abcd', 'qq.com')

In [31]: m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')

In [32]: m.group(0)

Out[32]: '010-12345'

In [33]: m.group(1)

Out[33]: '010'

In [34]: m.group(2)

Out[34]: '12345'

In [35]: m.groups()

Out[35]: ('010', '12345')

匹配html语言:

普通方式(group方法)

In [35]: s="<html><h1>redhat</h1></html>"

In [36]: reg=r"<\w+><\w+>\w+</\w+></\w+>"

In [37]: a=re.match(reg,s)

In [38]: a.group()

Out[38]: '<html><h1>redhat</h1></html>'

元组方式(groups方法应用:返回关键字)

In [39]: s="<html><h1>redhat</h1></html>"

In [40]: reg=r"<(\w+)><(\w+)>(\w+)</\2></\1>"

#这里给每个匹配到的组加括号表示元组中的一个元素,后面的2和1可以代替前面已经匹配到的第二个\w和第一个\w

In [41]: a=re.match(reg,s)

In [42]: a.groups()

Out[42]: ('html', 'h1', 'redhat')

In [43]: a.group()

Out[43]: '<html><h1>redhat</h1></html>'

匹配网址:

元组方式(groups方法应用:返回网址中的jishu和book关键字)

In [44]: s="http://www.redhat.org/jishu/book"

In [45]: reg=r"http://.+/(\w+)/(\w+)$"  #.表示匹配除了换行符"\n"之外的所有字符

#这里可以将想要匹配的关键字加括号,然后groups方法返回的元组中就会将这两个加括号的字符串作为元素

In [46]: a=re.match(reg,s)

In [47]: a.groups()

Out[47]: ('jishu', 'book')

In [48]: a.group()

Out[48]: 'http://www.redhat.org/jishu/book'

groupdict()方法

以字典方式返回符合条件的分组

In [52]: s="http://www.redhat.org/jishu/book"

In [53]: reg=r"http://.+/(?P<first_content>\w+)/(?P<second_content>\w+)$"

#以字典返回就必须加上一个key值,格式?P<>

In [54]: a=re.match(reg,s)

In [55]: a.groupdict()

Out[55]: {'first_content': 'jishu', 'second_content': 'book'}

In [56]: a.group()

Out[56]: 'http://www.redhat.org/jishu/book'

#可以看到无论是以元组返回关键字还是字典返回关键字都是不影响group方法正常使用的

In [57]: a.groups()

Out[57]: ('jishu', 'book')

In [5]: s="http://www.redhat.org/jishu/book/jishu/book"

In [6]: reg=r"http://.+/(?P<first_content>\w+)/(?P<second_content>\w+)/(?P=first_content)/(?P=second_content)$"

#如果有2个一样的关键字可以,可以在第二次匹配的时候直接调从第一次匹配到的字典里面取

In [7]: a=re.match(reg,s)

In [8]: a.groupdict()

Out[8]: {'first_content': 'jishu', 'second_content': 'book'}

In [9]: a.group()

Out[9]: 'http://www.redhat.org/jishu/book/jishu/book'

re高级用法

search()方法: 只找到符和条件的第一个并返回;
findall()方法: 返回符合条件的所有内容;
sub()方法: 对符合正则的内容进行替换;
split()方法: 指定多个分隔符进行分割;

search()方法

In [43]: s= "阅读次数为1000, 转发次数为100"

In [44]: a=re.search(r"\d+",s)

In [45]: print a
<_sre.SRE_Match object at 0x2289f38>

In [46]: print a.group()
1000

findall()方法

In [43]: s= "阅读次数为1000, 转发次数为100"

In [46]: b=re.findall(r"\d+",s)

In [47]: print b
['1000', '100']

sub()方法

In [43]: s= "阅读次数为1000, 转发次数为100"

In [49]: c=re.sub(r"\d+","0",s)

In [50]: print c
阅读次数为0, 转发次数为0

题目5:

执行脚本之后阅读次数和转发次数都加1

解答:

#coding:utf-8import re

s="阅读次数为1000, 转发次数为100"def addNum(x):

a=int(x.group()) +1#re方法出来的是字符串,需要先转换成整形才能进行+1运算

return str(a)

reg=r"\d+"#匹配s中的数字,至少包含一个数字的字符串print re.sub(reg,addNum,s)
#在sub()方法中调用函数不用写(),在这里s就是传入addNum函数的实参

split()方法

In [55]: s="wangzhe 18:98766"

In [56]: print re.split(r":| ",s)   #表示指定:和空格进行分隔
['wangzhe', '18', '98766']

python贪婪和非贪婪

默认情况下python正则是贪婪模式的

In [48]: s="this is a number 111-234-22-456"

In [49]: r=re.match(r".+(\d+-\d+-\d+-\d+)",s)

#.+表示匹配至少一个任意字符,这里的括号是groups方法的应用,可以查看前面groups的介绍

In [51]: r.group(1)

#查看第一个括号中匹配出的内容发现有两个1被.+匹配走了,只剩下了一个1,这是由于python默认的贪婪匹配导致的
Out[51]: '1-234-22-456'

非贪婪模式, 总是匹配尽可能少的字符

*, ?,+, {m,n}后面加上?, 使得贪婪模式变成非贪婪模式;

In [52]: s="this is a number 111-234-22-456"

In [53]: r=re.match(r".+?(\d+-\d+-\d+-\d+)",s)

In [54]: r.group(1)
Out[54]: '111-234-22-456'

JSON(JavaScript Object Notation)

是一种轻量级的数据交换格式。可以将字典转换为字符串,或者将字符串转换为字典

In [7]: dic={"service":"ftp","port":22}

In [8]: print json.dumps(dic)
{"port": 22, "service": "ftp"}

In [9]: print type(json.dumps(dic))
<type 'str'>

#coding:utf-8import json

dic={

"service":"ftp",

"port":22

}#将字典转换为字符串

in_json=json.dumps(dic,indent=4)#indent=4表示缩进为4,这样字符串就可以和上面字典的样子一样了print in_jsonprint type(in_json)#将字符串转换为字典

out_json=json.loads(in_json)print out_jsonprint type(out_json)

执行结果:

[root@python code12]# python json_test.py 
{
"port": 22, 
"service": "ftp"
}
<type 'str'>
{u'port': 22, u'service': u'ftp'}
<type 'dict'>

题目6:

获取ip地理位置

解答:

获取位置需要调用API,这里选择淘宝的API

#coding:utf-8import urllib2
#调用urllib2模块,可用于访问网址import json

ipadd=raw_input("输入要查询的IP:")

url="http://ip.taobao.com/service/getIpInfo.php?ip=%s" %(ipadd)#模拟浏览器访问指定链接

urlres=urllib2.urlopen(url)#读取访问的链接里面的内容

res=urlres.read()#print type(res) #可以看到这个API返回的内容是字符串,显然字符串很难处理,所以转换为字典就可以方便的处理了

res_dic=json.loads(res)#淘宝的API返回的是一个字典嵌套另一个字典,所以需要取两次keyprint "IP:%s" %(res_dic["data"]["ip"])print "Country:%s" %(res_dic["data"]["country"])print "Region:%s" %(res_dic["data"]["region"])print "City:%s" %(res_dic["data"]["city"])

执行结果:

[root@python code12]# python json_ip.py 
输入要查询的IP:110.65.0.124
IP:110.65.0.124
Country:中国
Region:广东省
City:广州市

参考文档:http://blog.csdn.net/gf_lvah/article/details/79034371

 总结

• re.match(p,text) :p 为正则表达式模式, text 要查找的字符串,会返回一个match 对象
• re.search(p,text) : 只要在 text 中匹配到了 p 就返回,只返回第一个匹配到的
• re.findall(p,text) :将能匹配上的全返回,会返回一个 list
• re.split(p,text) : 按照 p 匹配,并且以匹配到的字符为分隔符切割 text, 返回一个切割后的 list
• re.sub(p,s,text) : 替换,将 p 匹配到的字符替换为 s.
• pattern = re.compile(p) 先编译 p 模式,当正则表达式模式比较复杂的时候,会先编译,然后再使用

#coding:utf-8import re

mails=["aa.qq.com","redff@qq.com","21313@aa.com"]

reg = r"\w{4,20}@qq.com$"

reg=re.compile(reg)        #事先将正则匹配编译好,再一个一个去匹配,提高脚本效率for i in mails:

a=re.match(reg,i)

if a:

print "%s 合法" %(i)

else:

print "%s 不合法" %(i)

执行结果:

[root@python code12]# python compile_test.py 
aa.qq.com 不合法
redff@qq.com 合法
21313@aa.com 不合法

练习:

基础版:有一个日志文件access.log,统计访问前十的 IP 地址和访问次数
升级版:有多个日志文件access.log,统计访问前十的 IP 地址和访问次数

转载于:https://www.cnblogs.com/vaon/p/11177781.html

Python笔记(21)正则表达式相关推荐

  1. Python笔记---常用正则表达式练习

    Python笔记---正则表达式 1. \d :匹配一个数字字符.等价于 [0-9]. 2. \D:匹配一个非数字字符.等价于 [^0-9]. 3. \[ ] 4. \- 5. { }: 6. \* ...

  2. 【Python笔记】正则表达式

    正则表达式 行定位符 元字符 限定符 字符类 排除字符 选择字符 转义字符 分组 在 Python 中使用正则表达式语法 行定位符 行定位符就是用来描述子串的边界. "^" 表示行 ...

  3. python笔记之正则表达式

    正则表达式 正则表达式(regular expression) 什么正则表达式? 我们希望只提取出我们所关注的数据,此时就可以用正则表达式 正则表达式就是一种进行数据筛选的表达式 正则表达式就是用一种 ...

  4. 【Python笔记】正则表达式基础和应用

    文章目录 0 引言 0.1 正则の定义.功能 0.2 正则の基本知识 0.3 在常见的编辑器中使用正则の方法 0.4 进阶内容 1 基础篇 1.1 元字符:如何巧妙记忆正则表达式的基本元件? 1 特殊 ...

  5. python笔记:正则表达式

    1 正则表达式 带?的都是非贪婪匹配,匹配的越少越好 1.1 正则表达式中的转义符 注:\w还包含_ 大写的字母一般是"不"的意思 字符串开头和结尾一个A一个z正好是26个字母的开 ...

  6. Python 网络爬虫笔记6 -- 正则表达式

    Python 网络爬虫笔记6 – 正则表达式 Python 网络爬虫系列笔记是笔者在学习嵩天老师的<Python网络爬虫与信息提取>课程及笔者实践网络爬虫的笔记. 课程链接:Python网 ...

  7. Python学习笔记:正则表达式

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  8. 【Python笔记】使用 re 模块实现正则表达式操作

    使用 re 模块实现正则表达式操作 匹配字符串 使用 match() 方法进行匹配 使用 search() 方法进行匹配 使用 findall() 方法进行匹配 替换字符串 使用正则表达式分割字符串 ...

  9. python输出字体的大小_Toby的Python笔记 | 预备知识:安装openpyxl学做电子表格

    Toby的Python笔记 | 预备知识:安装openpyxl学做电子表格 Python 需要创建和读取excel表里面的数据,需要用 openpyxl 这个包,今天安装好备用. 首先,进入C命令窗口 ...

  10. c++ 冒泡排序_干货|python笔记1-冒泡排序

    面试的时候经常有面试官喜欢问如何进行冒泡排序?这个问题相信可以难倒一批的同学,本篇就详细讲解如何用python进行冒泡排序. 基本原理 01概念: 冒泡排序是一种交换排序,它的基本思想是:两两比较相邻 ...

最新文章

  1. mysql存储过程结构体_八、mysql视图、存储过程、函数以及时间调度器
  2. 谷歌服务中断事故能否避免?
  3. UNIX网络编程之旅-配置unp.h头文件环境
  4. 95 后大学生利用漏洞免费吃肯德基获刑
  5. 学习jQuery(一),做的第一个可拖动列的Grid
  6. 16个不错的 git 别名
  7. 数据结构与算法 - 递归回溯(迷宫问题)
  8. 嵌入式电路设计(soc底板电路设计)
  9. QT分析之网络编程(七)
  10. “狼牙抓鸡”现身IT江湖
  11. html生成jsessionid,H5 APP 使用 JSESSIONID 保持会话登录
  12. 腾讯云个人账号实名认证图文详情 新手必看教程
  13. 业务型团队如何提高人效
  14. SSH的 The authenticity of host xxx.xxx.xxx.xxx can't be established. 问题
  15. 基于墨刀实现的原型系统:一款简易的读书软件
  16. Android实战技巧之十:获得屏幕物理尺寸、密度及分辨率
  17. 2020ICPC济南K Kth Query
  18. 百度android 升级,百度浏览器去广告版下载-百度浏览器v6.4.21安卓去广告去升级版-ucbug软件站...
  19. ZBar条型码、二维码
  20. 2020年Android开发年终总结之如何挤进一线大厂?(1),androidapp开发工具

热门文章

  1. 计算机动漫与游戏制作电脑配置,动漫与游戏设计该如何选电脑配置?
  2. jieba库词频统计_jieba库的使用与词频统计
  3. h3c交换机重启_华三交换机重启命令(范文篇).doc
  4. MCGS 昆仑通态触摸屏 modbus TCP 数据转发
  5. 全网最详细的下载、安装和使用绘图神器draw.io(drawio),它比visio,processon,wps,亿图图示等更好用,最重要的是它免费
  6. 孙玄:人工智能时代,你需要掌握的经典大规模文本相似识别架构和算法
  7. CodeForces - 988D(思维STL)
  8. IT自动化运维平台建设解决方案
  9. 单片机c语言 教案,《单片机C语言》 课程教案.doc
  10. plc secs半导体通讯协议 PLC 与MES的SECS/GEM通讯方案