正则表达式

  正则表达式,英文:Regular Expression。它一般用来检索和替换符合某种模式的文本。正则表达式

  Python自1.5版本开始增长了re模块,使得Python拥有了所有的正则表达式功能。函数

1、基本函数(match、search、findall)

  在使用re模块以前,要先引入,re模块使已经在内置在Python内部的,无需再本身下载安装了。spa

1 import re

一、re.match函数

1.1 原型:match(pattern, string, flags=0)
1.2 参数:
  pattern:匹配的正则表达式
  string:要匹配的字符串
  flags:标志位,用来控制正则表达式的匹配方式
    re.I:忽略大小写
    re.L:作本地化识别
    re.M:多行匹配,影响^和$
    re.S:使.匹配包括换行符在内的全部字符,不然.不匹配换行符
    re.U:根据Unicode字符集解析字符,影响'\w \W \b \B'
    re.X:使咱们以更灵活的格式理解正则表达式
1.3 功能:尝试从字符串的起始位置匹配一个模式code

1.4 eg:对象

1 # 注释为输出结果
2 
3 print(re.match('www', 'www.baidu.com')) 4 # <_sre.SRE_Match object; span=(0, 3), match='www'>
5 # 返回结果的类型、匹配结果的位置、匹配内容
6 
7 print(re.match('www', 'www.baidu.com').span()) 8 # (0, 3) 输出匹配的位置

二、re.search函数

2.1 原型:search(pattern, string, flags=0)
2.2 参数:
  pattern:匹配的正则表达式
  string:要匹配的字符串
  flags:标志位,用来控制正则表达式的匹配方式(与上面内容一致,后面不赘述)
2.3 功能:扫描整个字符串,返回第一个成功的匹配,与match相比,就是没必要从起始位置开始匹配blog

三、re.findall函数

3.1 原型:findall(pattern, string, flags=0)
3.2 参数:
  pattern:匹配的正则表达式
  string:要匹配的字符串
  flags:标志位,用来控制正则表达式的匹配方式
3.3 功能:扫描整个字符串,返回结果列表,其中匹配到全部符合模式的结果索引

 2、正则表达式的元字符

一、匹配单个字符

.ci

能够匹配除换行符之外的任意字符字符串

[]原型

是字符集合,表示匹配方括号中任意所包含的任一字符

[asd]

匹配其中任一字符

[a-z]

匹配任意小写字母

[0-9a-zA-Z_]

匹配任意大小写字母或数字或下划线

[^asd]

匹配除了asd几个字母之外的全部字符,中括号里的^号称为'脱字符',表示不匹配集合中的字符

[^0-9]

匹配全部非数字字符

\d

匹配数字,效果同[0-9]

[^\d]

匹配非数字字符,效果同[^0-9]

\w

匹配数字,字母和下划线,效果同[0-9a-zA-Z_]  (字母不包含空格)

\W

匹配非数字,字母和下划线,效果同[^0-9a-zA-Z_]

\s

匹配任意的空白符(空格,换行,回车,换页,制表),效果同[ \f\n\r\t]

\S

匹配任意的非空白符,效果同[^ \f\n\r\t]

二、锚字符(边界字符)

^

行首匹配,和在中括号里的^不是一个意思

$

行尾匹配

\A

匹配字符串的开始,他和^的区别是,\A只匹配整个字符串的开头,即便在re.M下也不会匹配他行的行首

\Z

匹配字符串的结束,他和$的区别是,\Z只匹配整个字符串的结束,即便在re.M下也不会匹配他行的行尾

\b

匹配一个单词的边界,也就是指单词和空格间的位置 egr'er\b',匹配以er为结尾边界的位置

\B

匹配非单词边界,与上面相反,匹配不是边界的

三、多个字符

(xyz)

匹配小括号内的xyz,做为一个总体去匹配

x?

匹配0个或者1x

egprint(re.findall(r"a?","aaabaa")) # 非贪婪匹配,尽量少的匹配

x*

匹配0个或者任意多个x

egprint(re.findall(r"a*","aaabaa")) # 贪婪匹配,尽量多的匹配

x+

匹配至少一个x(贪婪匹配)

x{n}

匹配肯定的nxn是一个肯定的非负整数

x{n,}

匹配至少nx

x{n,m}

匹配至少n个,最多mx,注意n<=m

x|y

|表示或,匹配的是xy

四、特殊状况

*? +? x?

最小匹配,一般都是尽量多的匹配,可使用这种解决贪婪匹配

(?:X)

相似于(xyz),但不表示一个组

3、实用技巧

一、字符串切割

1 str1 = "hello world hello world hello world "
2 # 普通切割
3 print(str1.split(' '))  # 仅仅以一个空格切割,遇到多个空格时会出现不想要的内容
4 # 正则切割
5 print(re.split(r' +', str1))  # 能够经过正则的切割,其中利用正则的方法,来以任意多个空格来切割

二、re.finditer函数

  • 原型:finditer(pattern, string, flags=0)
  • 参数:
    • pattern:匹配的正则表达式
    • string:要匹配的字符串
    • flags:标志位,用来控制正则表达式的匹配方式
  • 功能:与findall相似,扫描整个字符串,返回的是一个迭代器,能够节省空间,提升效率
1 str2 = "hello world hello world hello world hello world hello world"
2 
3 d = re.finditer(r'hello', str2) 4 while True: 5     # 当使用迭代方法时,为了可使他在找完对象后退出,通常经过捕获的方法
6     try: 7       print(next(d)) 8     except StopIteration as e: 9       break

三、字符串的替换和修改

  • sub(pattern, repl, string, count=0, flags=0)
  • subn(pattern, repl, string, count=0, flags=0)功能: 在目标字符串中以正则表达式的规则匹配字符串,再把他们替换成指定的字符串。能够指定替换的次数,若是不指定,替换全部的匹配字符串
    • pattern: 正则表达式(规则)
    • repl: 指定的用来替换的字符串
    • string: 目标字符串
    • count: 最多替换次数
    • flags:
  • 区别: sub返回一个字符串,subn返回一个元组(第一个元素是替换后的字符串,第二个元素是替换的个数)

四、分组

  概念:除了简单的判断是否匹配之外,正则表达式还有提取子串的功能。用()表示的就是提取分组。(这个本身试一下,加深印象)

 1 str3 = "010-12312323"
 2 m = re.match(r'(?P<first>\d{3})-(\d{8})', str3)  3 # 使用序号获取对应组的信息,group(0)一直表明的原始字符串
 4 print(m.group(0))  5 print(m.group(1))  6 print(m.group('first'))  # 使用本身起的名字索引
 7 print(m.group(2))  8 
 9 print(m.groups())  # 查看各组的状况
10 
11 # 若是在最外层加一个括号,那么group(1)就是打印的最外面的那个,依次向里
12 
13 # ?P<first>写在小括号里,表示起名字

五、编译

  • 当咱们使用正则表达式时,re模块会干两件事:

  (1)编译正则表达式,若是正则表达式自己不合法,会报错
  (2)用编译后的正则表达式去匹配对象

  • 编译的原型:re.compile(pattern, flags=0)

  提示:通常状况下,比较简单的匹配咱们直接经过上面讲述的那几种基本方法就能够了,可是当模式比较复杂,或者这个正则对象在后面还会用到时,就会先把他编译出来,毕竟后面能够省去再次编译的时间,而且更清晰。

  正则对象,习惯上命名为   re_xxxxxx。

1 pat = r"^1(([3578]\d)|(47))\d{8}$" # 模式
2 re_telephone = re.compile(pat)  # 编译成正则对象
3 print(re_telephone.match("13612345678"))  # 使用其匹配文本,前面提到的基本方法在这里照常使用