跳转至

正则表达式

正则表达式有多重要,这可是上古神兽,任何语言都不能忽略的技能槽。

国际惯例,需要官方无微不至的关怀的请出门左转:正则表达式HOWT

白话正则

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。 例,你想在一堆人名中找和你同名的人,描述语法为:

不管你姓啥,名字叫'明'站出来

来试一试正则的魅力:

import re

names = '''
小小明
小明
小头
大明
大大明
大头
'''

m = re.findall(r'.+明', names, re.M)
print(m)

输出:

['小小明', '小明', '大明', '大大明']

正则表达式语法规则

正则表达式是一套独立于语言之外的语法规则,各种语言都遵守这套规则来实现了正则匹配,最基础的正则语法(需熟练掌握):

常用的元字符

语法 说明
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束

重复

语法 说明
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次

分枝

使用 | 标识分歧,可类比编程语言中的‘或’

固定电话号码正则:

0\d{2}-\d{8}|0\d{3}-\d{7}

匹配两种以连字号分隔的电话号码: 1. 3位区号,8位本地号(如001-12345678); 2. 4位区号,7位本地号(0123-1234567)。

分组

使用 ( ) 标识分组:

IP地址正则:

(\d{1,3}\.){3}\d{1,3}
  1. \d{1,3}匹配1到3位的数字;
  2. (\d{1,3}.){3}匹配三位数字加上一个英文句号(分组)重复3次;
  3. 最后再加上一个一到三位的数字(\d{1,3})

反义

使用 ^ 标识取反:

匹配用尖括号括起来的以a开头的字符串

<a[^>]+>
语法 说明
\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符

基础语法规则实践

模式 描述
[Pp]ython 匹配 "Python" 或 "python"
[0-9] 匹配任何数字。类似于 [0123456789]
[a-z] 匹配任何小写字母
[^0-9] 匹配除了数字外的字符

主要函数

现在尝试再用正则的语法去理解上述代码,我们首先导入了re模块,这是Python内置的正则模块。 它实现了很多功能,包括且不限于'match','search','findall'等等。

findall

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。

match

尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回None。

import re
# 在起始位置匹配成功匹配到www,并使用span返回了匹配成功的位置元祖数据
print(re.match('www', 'www.easypython.cn').span())  
# 起始位置匹配匹配easypython失败返回None
print(re.match('easypython', 'www.easypython.cn'))  

输出:

(0, 3)
None

group(num) 或 groups()

使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。

import re

line = "Cats are smarter than dogs"

matchObj = re.match(r'(.*) are (.*?) .*', line, re.M | re.I)

if matchObj:
    #整个字符串匹配成功
    print("matchObj.group() : ", matchObj.group())
    #(.*) 匹配成功
    print("matchObj.group(1) : ", matchObj.group(1))
    #(.*?) 匹配成功
    print("matchObj.group(2) : ", matchObj.group(2))
else:
    print("No match!!")

执行结果如下:

matchObj.group() :  Cats are smarter than dogs
matchObj.group(1) :  Cats
matchObj.group(2) :  smarter

扫描整个字符串并返回第一个成功的匹配。 searchmatch不同的地方在于, search搜索整个字符串,任意子串符合正则就算成功匹配; 而match是从开始位置进行匹配,字符串开始不符合正则表达式,则匹配失败。

import re
#找到符合正则表达式的子串就使用span返回了匹配成功的位置元祖数据
print(re.search('www', 'www.easypython.cn').span())  
print(re.search('easypython', 'www.easypython.cn').span())

输出:

(0, 3)
(4, 14)

compile

compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match()search() 使用。

import re
pattern = re.compile('easypython') 
print(pattern.search('www.easypython.cn').span())

sub

sub用于替换字符串中的匹配项。

import re
site = 'www.笔者.cn'
site = re.sub('笔者', "easypython", site)
print(site)

split

split 方法按照能够匹配的子串将字符串分割后返回列表

import re
strs = re.split('\W+','www.easypython.cn')
print(strs)
#输出 ['www', 'easypython', 'cn']

参考链接: