1. 正则表达式基础

1.1. 简单介绍

正则表达式并不是Python的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大。得益于这一点,在提供了正则表达式的语言里,正则表达式的语法都是一样的,区别只在于不同的编程语言实现支持的语法数量不同;但不用担心,不被支持的语法通常是不常用的部分。如果已经在其他语言里使用过正则表达式,只需要简单看一看就可以上手了。

下图展示了使用正则表达式进行匹配的流程:

                                                                                                                         re_simple_38246a58-83be-4adf-9f30-6d735e9b9b47

正则表达式的大致匹配过程是:依次拿出表达式和文本中的字符比较,如果每一个字符都能匹配,则匹配成功;一旦有匹配不成功的字符则匹配失败。如果表达式中有量词或边界,这个过程会稍微有一些不同,但也是很好理解的,看下图中的示例以及自己多使用几次就能明白。

下图列出了Python支持的正则表达式元字符和语法: 

                                                                                      pyre_ebb9ce1c-e5e8-4219-a8ae-7ee620d5f9f1

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())
匹配IP v4地址

匹配组地址:

  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())
匹配E-mail