1. 正则表达式基础
1.1. 简单介绍
正则表达式并不是Python的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大。得益于这一点,在提供了正则表达式的语言里,正则表达式的语法都是一样的,区别只在于不同的编程语言实现支持的语法数量不同;但不用担心,不被支持的语法通常是不常用的部分。如果已经在其他语言里使用过正则表达式,只需要简单看一看就可以上手了。
下图展示了使用正则表达式进行匹配的流程:
正则表达式的大致匹配过程是:依次拿出表达式和文本中的字符比较,如果每一个字符都能匹配,则匹配成功;一旦有匹配不成功的字符则匹配失败。如果表达式中有量词或边界,这个过程会稍微有一些不同,但也是很好理解的,看下图中的示例以及自己多使用几次就能明白。
下图列出了Python支持的正则表达式元字符和语法:
1.2. 数量词的贪婪模式与非贪婪模式
正则表达式通常用于在文本中查找匹配的字符串。Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪的则相反,总是尝试匹配尽可能少的字符。例如:正则表达式"ab*"如果用于查找"abbbc",将找到"abbb"。而如果使用非贪婪的数量词"ab*?",将找到"a"。
1.3. 反斜杠的困扰
与大多数编程语言相同,正则表达式里使用"\"作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符"\",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\\\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"\\"表示。同样,匹配一个数字的"\\d"可以写成r"\d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。
1.4. 匹配模式
正则表达式提供了一些可用的匹配模式,比如忽略大小写、多行匹配等,这部分内容将在Pattern类的工厂方法re.compile(pattern[, flags])中一起介绍。
以上引用AstralWind博客,原文地址:http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html
2. re模块
2.1. 开始使用re
Python通过re模块提供对正则表达式的支持。使用re的一般步骤是先将正则表达式的字符串形式编译为Pattern实例,然后使用Pattern实例处理文本并获得匹配结果(一个Match实例),最后使用Match实例获得信息,进行其他的操作。
1 import re #导入模块名 2 3 pattern = re.compile("^[0-9]") #生成要匹配的正则对象 , ^代表从开头匹配,[0-9]代表匹配0至9的任意一个数字, 所以这里的意思是对传进来的字符串进行匹配,如果这个字符串的开头第一个字符是数字,就代表匹配上了 4 5 match = pattern.match('14534Abc') #按上面生成的正则对象 去匹配 字符串, 如果能匹配成功,这个m就会有值, 否则m为None<br><br>if m: #不为空代表匹配上了 6 print(match.group()) #m.group()返回匹配上的结果,此处为1,因为匹配上的是1这个字符<br>else:<br> print("doesn't match.")<br> 7 8 #也可以写成: 9 match = pattern.match("^[0-9]",'14534Abc')
效果是一样的,区别在于,第一种方式是提前对要匹配的格式进行了编译(对匹配公式进行解析),这样再去匹配的时候就不用在编译匹配的格式,第2种简写是每次匹配的时候 都 要进行一次匹配公式的编译,所以,如果你需要从一个5w行的文件中匹配出所有以数字开头的行,建议先把正则公式进行编译再匹配,这样速度会快点。
正则表达式常用5种操作
re.match(pattern, string) # 从头匹配
re.search(pattern, string) # 匹配整个字符串,直到找到一个匹配
re.split() # 将匹配到的格式当做分割点对字符串分割成列表
1 >>>m = re.split("[0-9]", "alex1rain2jack3helen rachel8") 2 >>>print(m)
输出: ['alex', 'rain', 'jack', 'helen rachel', '']
re.findall() # 找到所有要匹配的字符并返回列表格式
1 >>>m = re.findall("[0-9]", "alex1rain2jack3helen rachel8") 2 >>>print(m)<br>
输出:['1', '2', '3', '8']
re.sub(pattern, repl, string, count,flag) # 替换匹配到的字符
1 m=re.sub("[0-9]","|", "alex1rain2jack3helen rachel8",count=2 ) 2 print(m)
输出:alex|rain|jack3helen rachel8
re.match与re.search的区别
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
常见的正规实例:
匹配手机号码:
1 phone_str = "hey my name is alex, and my phone number is 13651054607, please call me if you are pretty!" 2 phone_str2 = "hey my name is alex, and my phone number is 18651054604, please call me if you are pretty!" 3 4 m = re.search("(1)([3-8]\d{9})",phone_str2) 5 if m: 6 print(m.group())
匹配IP v4地址:
1 ip_addr = "inet 192.168.60.223 netmask 0xffffff00 broadcast 192.168.60.255" 2 3 m = re.search("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", ip_addr) 4 5 print(m.group())
匹配组地址:
1 contactInfo = 'Oldboy School, Beijing Changping Shahe: 010-8343245' 2 match = re.search(r'(\w+), (\w+): (\S+)', contactInfo) #分组 3 """ 4 >>> match.group(1) 5 'Oldboy School' 6 >>> match.group(2) 7 'Beijing Changping Shahe' 8 >>> match.group(3) 9 '010-8343245' 10 """ 11 match = re.search(r'(?P<last>\w+), (?P<first>\w+): (?P<phone>\S+)', contactInfo) 12 """ 13 >>> match.group('last') 14 'Oldboy School' 15 >>> match.group('first') 16 'Beijing Changping Shahe' 17 >>> match.group('phone') 18 '010-8343245' 19 """
匹配E-mail:
1 email = "alex.li@126.com http://www.oldboyedu.com" 2 3 m = re.search(r"[0-9.a-z]{0,26}@[0-9.a-z]{0,20}.[0-9a-z]{0,8}", email) 4 print(m.group())