概述

正则表达式,Regular Expression,缩写为regex,regexp,RE等。正则表达式是文本处理中重要的基数,可以对字符串按照某种规则进行检索、匹配、替换等操作。

分类

  • BRE:基本正则表达式,grep、sed、vi等均支持,vim有扩展表达式
  • ERE:扩展正则表达式,egrep(grep -E)、sed -r等
  • PCRE:几乎所有高级语言都是PCRE的变种,可以认为是PCRE的子集,python模块为re

基本语法

元字符metacharacter

代码 说明 示例
. 匹配除换行符外任意一个字符 .
[abc] 字符集合,只能表示一个字符位置,匹配所包含的任意一个字符 [abc]匹配plain中的’a’
[^abc] 字符集合,表示一个字符位置,匹配除去集合内字符的任意一个字符 [^abc]可以匹配plain中的’p’,’l’,’i’或’n’
[a-z] 字符范围,表示一个字符位置,匹配所包含的任意一个字符 [a-z] [0-9]
\b 匹配单词的边界 \bb在文本中找到单词中b开头的b字符
\B 不匹配单词的边界
\d [0-9]匹配一个数字
\D [^0-9] 匹配1位非数字
\s 匹配一位空白字符,包括换行符、制表符、空格[\f\r\n\t\v]
\S 匹配一位非空白字符
\w 匹配[a-zA-Z0-9_],包括中文字
\W 匹配\w之外的字符

转义

在正则表达式中要将有特殊意义的符号表示它的本意,可使用\转义,如\ \表示为\自身

重复

代码 说明 举例
* 表示前面的正则表达式会重复0次或多次 e\w*单词中e后面可以有非空字符
+ 表示前面的正则表达式重复至少1次 e\w+单词中e后面至少有一个非空白字符
? 或1次 e\w+单词中e后面最多只能有一个非空白字符
{n} 重复固定{n}次 e\w+单词中e后面只能有n个非空白字符
{n,} 重复至少n次 e\w{1,}等价e\w+
e\w{0,}等价e\w*
e\w{0,1}等价e\w?
{n.m} 重复n到m次 e\w{1,10}单词中e后面至少1个,最多10个非空白字符

贪婪与非贪婪

默认是贪婪模式,既尽可能多的匹配更长的字符串

非贪婪模式在重复符号后面加一个?就尽量少的匹配了

代码 说明
*? 匹配任意次,但尽可能少的重复
+? 匹配至少一次,但尽可能少的重复
?? 匹配0次或1次,但尽可能少的重复
{n,}? 匹配至少n次,但尽可能少的重复
{n,m}? 匹配至少n次,最多m次,但尽可能少的重复
  1. In [1]: import re
  2. In [2]: str = "very very very happy"
  3. In [3]: re = re.compile('v.*?y') # 使用非贪婪模式,尽可能少的匹配
  4. In [4]: re.findall(str)
  5. Out[4]: ['very', 'very', 'very']
  6. In [3]: re = re.compile('v.*y') # 使用贪婪模式,尽可能多的匹配
  7. In [4]: re.findall(str)
  8. Out[4]: ['very very very happy']

Python正则表达式

Python使用re模块提供了正则表达式处理的能力

编译

re.compile(pattern, flags=0)

设定flags,编译模式,返回正则表达式对象regex。

pattern就是正则表达式字符串,flags是选项,正则表达式需要被编译,提高了效率,这些编译后的结果被保存,下次使用同样的pattern的时候,就不会再次编译,re的其他方法都调用了编译方法来提高效率

单次匹配

  • match

re.match(pattern, string, flags=0)

regex.match(string[, pos[,endpos]])

match从字符串的开头匹配,regex对象match方法可以重新设定开始位置和结束位置,返回match对象

  • search

re.search(pattern, string, flags=0)

regex.search(string[, pos[,endpos]])

从头搜索直到第一个匹配,regex对象match方法可以重新设定开始位置和结束位置,返回match对象

  • fullmatch

re.fullmatch(pattern, string, flags=0)

整个字符串和正则表达式匹配

  1. import re
  2. s = '''bottle\nbag\nbig\napple'''
  3. result = re.match('b', s) # 找到一个就结束
  4. print(result)
  5. result = re.match('a', s) # 没有从开头找到,返回None
  6. print(result)
  7. result = re.search('b', s) # 扫描字符串匹配第一个位置
  8. print(result)
  9. result = re.search('a', s)
  10. print(result)

全文搜索

  • findall

re.findall(pattern, string, flags=0)

对整个字符串,从左至右匹配,返回所有匹配项的列表

  • finditer

re.finditer(pattern, string, flag=0)

对整个字符串,从左至右匹配,返回所有匹配项,返回迭代器,每次迭代返回的是match对象

  1. import re
  2. s = '''bottle\nbag\nbig\napple'''
  3. result = re.findall('b', s)
  4. print(result)
  5. result = re.finditer('b', s)
  6. print(result)
  7. # ['b', 'b', 'b']
  8. # <callable_iterator object at 0x102ab0240>

匹配替换

re.sub(pattern, replacement, string, count=0, flags=0)

使用pattern对字符串string进行匹配,对匹配项使用replacement替换

replacement可以是string、bytes、function

  1. s = '''bottle\nbag\nbig\napple'''
  2. result = re.sub('b\wg','hahha', s)
  3. print(result)