python(十一) 正则表达式
正则表达式(re=regular expression)
正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,
否则,该字符串就是不合法的
一个完整的正则使用过程
# 第一个参数是你正则的规则, 第二个参数是检测的字符串;
# 如果找到匹配, 则返回一个对象;
a = re.match(r"westos", "westoshello")
print a.group()
a = re.match(r"westos", "hellowestoshello")
print a
# 如果没有找到匹配, 则返回 None ;
\d 单个数字
\D \d的取反 , 除了数字之外In [15]:
import re
a = re.match(r"\d", "1")
a.group()
a = re.match(r'\d', "w11")
print a
In [19]: a = re.match(r"\D","we111123we")
In [20]: a.group()
Out[20]: 'w'
In [21]: a = re.match(r"\D","@111123we")
In [22]: a.group()
Out[22]: '@'
\s 匹配空格, \n, \t,\r
\S 非空格
In [23]: a = re.match(r"\s","\twe")
In [24]: a
Out[24]: <_sre.SRE_Match at 0x3183d30>
In [25]: a.group()
Out[25]: '\t'
In [26]: a = re.match(r"\S","we\twe")
In [27]: a.group()
Out[27]: 'w'
\W: 非~
In [28]: a = re.match(r"\w","_111123we")
In [29]: a.group()
Out[29]: '_'
In [30]: a = re.match(r"\w","a_11123we")
In [31]: a.group()
Out[31]: 'a'
In [32]: a = re.match(r"\W","@11123we")
In [33]: a.group()
Out[33]: '@'
In [34]: a = re.match(r"\W","11123we")
字符 功能
* 匹配前一个字符出现0次或无限次, 即可有可无, {0,}
+ 匹配前一个字符出现1次或无限次,即至少出现一次, {1,}
? 匹配前一个字符出现1次或0次,即前面的字符可省略, {0,1}
{m,} 匹配前一个字符至少出现m次
{m,n} 匹配前一个字符出现m次到n次
应用1: 匹配电话号
import re reg = r"010-?\d{8}$" phones = ["010-1234567899", "01012345678", "010123"] for i in phones: a = re.match(reg, i) if a: print a.group() else: print "%s 不合法" %(i)
需求: 匹配出, 字符串第一个字母为大写字母, 后面都是小写字母, 并且
这些小写字母可有可无;
s = ["hello", "Hello", "hAll"]
import re
s = ["hello", "HelloH", "hAll", "A", "a"]
reg = r"[A-Z][a-z]*"
for i in s:
a = re.match(reg, i)
if a:
# group 方法只会打印出符和条件的内容 ;
print "%s 合法" %(i)
else:
print "%s不合法 " %(i)
^ : 以什么开头
$ : 以什么结尾
应用3: 匹配qq邮箱
找出列表中符和条件的邮箱地址, 并存储到/tmp/mail.txt文件中;
邮箱地址以@qq.com结尾;
@qq.com前面的内容由字母,数字或者下划线组成, 但至少4位, 最多20位;
import re li = ["[email protected]","westos.qq.com","[email protected]","[email protected]"] def ruler(s): reg = r"\w{4,20}@qq.com$" a = re.match(reg,s) if a: return True else: return False m = [i for i in li if ruler(i)!=False ] with open("/tmp/mail.txt", "a+") as f: for s in m: f.write(s + "\n")
表示分组
| : 匹配| 左右任意一个表达式即可;
应用4: 匹配出0-100之间的数字, 包括1和100
注意:须考虑 一位数 0-9,两位数 10-99,三位数 100reg = r"^0$|^100$|[1-9]\d?$"
(ab): 将括号中的字符作为一个分组
\num: 引用分组第num个匹配到的字符串
(?P): 分组起别名(?P=name) : 引用分组的别名In [70]:
# reg = r"<\w+><\w+>\w+</\w+></\w+>"
s = "<html><h1>westos</h1></html>"
reg = r"<(\w+)><(\w+)>(\w+)</\2></\1>"
a = re.match(reg, s)
a.group()
a.groups()
( )组的用法
s = 'http://www.westos.org/jishu/sheji'
In [76]: reg =r"http://.+/(\w+)/(\w+)$"
In [77]: a = re.match(reg,s)
In [78]: a.group()
Out[78]: 'http://www.westos.org/jishu/sheji'
In [79]: a.groups()
Out[79]: ('jishu', 'sheji')
?p 别名的用法
s = 'http://www.westos.org/jishu/sheji'
In [76]: reg =r"http://.+/(\w+)/(\w+)$"
In [77]: a = re.match(reg,s)
In [78]: a.group()
Out[78]: 'http://www.westos.org/jishu/sheji'
In [79]: a.groups()
Out[79]: ('jishu', 'sheji')
search()方法: 只找到符和条件的第一个并返回;
findall()方法: 返回符合条件的所有内容;
sub()方法: 对符合正则的内容进行替换;
import re s = "阅读次数为1000, 转发次数为100" reg = r"\d+" a = re.search(reg, s) print a.group() print re.findall(reg, s) print re.sub(reg, '88' , s) def addNum(x): # a 是整形 a = int(x.group()) + 1 return str(a) print re.sub(reg, addNum, s)
split()方法: 指定多个分隔符进行分割;
非贪婪模式, 总是匹配尽可能少的字符;
*, ?,+, {m,n}后面加上?, 使得贪婪模式编程非贪婪模式
In [111]: s = "This is a number 111-234-22-456"
In [112]: r = re.match(r".+(\d+-\d+-\d+-\d+)", s)
In [113]: r.group(1)
Out[113]: '1-234-22-456'
In [114]: r1 = re.match(r".+?(\d+-\d+-\d+-\d+)", s)
In [115]: r1.group(1)
Out[115]: '111-234-22-456'
JSON
如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便
json(javascript object)
import json dic = { "service": "ftp", "port": 22, "service1": "ftp", "port1": 22 } in_json = json.dumps(dic ,indent=4) ##把Python对象变成一个JSON print type(in_json) print in_json out_json = json.loads(in_json) ##将json输出为python对象 print type(out_json)
json应用案例: 获取你输入IP的所在地理位置;
import urllib2 import json ipadd = raw_input("IP:") url = "http://freegeoip.net/json/%s"%(ipadd) # 模拟浏览器访问指定链接 urlres = urllib2.urlopen(url) ##打开浏览器访问链接 res = urlres.read() ##获取api信息 res_dic = json.loads(res) ##转化为python对象 print """ 15 查询结果显示: 16 IP: {} 17 Country: {} 18 longitude:{} 19 latitude: {} 20 """.format(res_dic['ip'], res_dic['country_name'], res_dic['longitude'],res_dic['latitude'])
输出结果: