目录
正则匹配可以说是数据检索和遍历的基础技能了。在Python我们经常会用到需要提出特定字符的场景,尤其在网络爬虫爬取的编码后杂乱网页提取数据的的时候。在数据库提取数据后或是JSON文件做二次处理都需要re库进行提取。因此学好re库和正则表达是python工程师的必修课,你可以对正则表达式掌握的不是很熟练,但是必须要了解re库中存在的各种函数功能,这将大大加速你完成项目某项需求的时间也方便进行问题搜索。本文将详细介绍Python中正则表达式功能re库的功能。
正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符"),是计算机科学的一个概念。正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,该模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本。
许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开来的,后来在广泛运用于Scala 、PHP、C# 、Java、C++ 、Objective-c、Perl 、Swift、VBScript 、Javascript、Ruby 以及Python等等。正则表达式通常缩写成“regex”,单数有regexp、regex,复数有regexps、regexes、regexen。
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
给定一个正则表达式和另一个字符串,我们可以达到如下的目的:
正则表达式的特点是:
re库是Python自带的标准库,不需要安装即可使用:
Re库默认采用贪婪匹配,即输出匹配最长的子串
import re
模块常用函数:
基础语法形式为:
re.match(pattern,string,flags=0)
函数功能为 :从一个字符串的开始位置起匹配正则表达式,返回match对象。如果开始没有匹配到,不管后边有没有能符合匹配的,都打印不出结果,这是和search的区别。
参数说明:
其中flags可选参数有:
参数 | 说明 |
re.l/re.IGNORECASE | 忽略大小写 |
re.M/re.MULTILINE | 多行模式,改变‘^'和'$'的行为 |
re.S/re.DOTALL | 点'.'的任意匹配模式,改变’.‘的行为 |
re.L/re.LOCALE | 使预定字符类\w\W\b\B\s\S取决于当前区域设定 |
re.U/re.UNICODE | 使预定字符类\w\W\b\B\s\S\d\D取决于unicode定义的字符属性 |
re.X/re.VERBOSE | 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并且可以加入注释 |
我们把复杂的匹配放到第三章再写,这里我们仅简单展示一下该函数的用法和效果:
- strings='Fanstuck wants to leave alone'
- print(re.match('Fanstuck',strings))
- #out: <re.Match object; span=(0, 8), match='Fanstuck'>
其中span就匹配到的pattern在字符串中的位置。
- strings='Fanstuck wants to leave alone'
- print(re.match('anstuck',strings))
- #out: None
基础语法格式为:
fullmatch(pattern, string, flags=0)
参数说明:
函数功能为 :尝试将正则表达式pattern应用于所有字符串string,如果匹配成功,返回匹配对象;如果找不到匹配,则为“None”。
用法效果展示:
- strings='Fanstuck wants to leave alone'
- print(re.fullmatch('Fanstuck wants to leave alone',strings))
- #out: <re.Match object; span=(0, 29), match='Fanstuck wants to leave alone'>
该函数为贪婪规则指定的pattern都必须完全和strings长度和字符一一对应,否则就是None:
- strings='Fanstuck wants to leave alone'
- print(re.fullmatch('Fanstuck wants to leave alon',strings))
- #out: None
基础语法格式为:
search(pattern, string, flags=0)
参数说明:
函数功能为 :扫描字符串string以查找与正则表达式pattern的匹配项,返回匹配对象;如果找不到匹配,则为“None”。 re.search 匹配整个字符串,直到找到一个匹配。
- strings='Fanstuck wants to leave alone'
- print(re.search('alone',strings))
- #out:<re.Match object; span=(24, 29), match='alone'>
- strings='Fanstuck wants to leave alone'
- print(re.search('die',strings))
- #out:None
基本语法格式为:
sub(pattern, repl, string, count=0, flags=0)
参数说明:
- strings='Fanstuck wants to leave alone alonely'
- print(re.sub('leave','die',strings))
- #out:Fanstuck wants to die alone alonely
- strings='Fanstuck wants to leave alone alonely'
- print(re.sub('alone','sad',strings))
- #out:Fanstuck wants to leave sad sadly
基础语法格式为:
subn(pattern, repl, string, count=0, flags=0)
参数说明:
与前一个函数sub相比,无非就是增加了一个次数:
- strings='Fanstuck wants to leave alone alonely'
- print(re.subn('alone','sad',strings))
- #out:('Fanstuck wants to leave sad sadly', 2)
但是转化为字典dict或者是用于pandas都是比较方便的,不用在统计出匹配了多少个字段。
基础语法格式为:
- findall(pattern, string, flags=0)
- 或
- findall(pattern,string, pos, endpos)
参数说明:
函数功能为 :在字符串string中匹配所有符合正则表达式pattern的对象,并把这些对象通过列表list的形式返回。
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('alone',strings))
- #out:['alone', 'alone']
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('alonely',strings))
- #out:['alonely']
- strings='Fanstuck wants to leave alone alonely'
- pattern=re.compile('a')
- print(pattern.findall(strings,0,30))
基础语法格式为:
finditer(pattern, string, flags=0)
参数说明:
函数功能为:在字符串string中匹配所有符合正则表达式pattern的对象,并把这些对象通过迭代器的形式返回。
- strings='Fanstuck wants to leave alone alonely'
- result=re.finditer('alone',strings)
- for i in result:
- print(i)
- #out:<re.Match object; span=(24, 29), match='alone'>
- #out:<re.Match object; span=(30, 35), match='alone'>
基础语法格式为:
compile(pattern, flags=0)
compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。
- strings='Fanstuck wants to leave alone alonely'
- pattern=re.compile('to')
- pattern.search(strings)
- #out:<re.Match object; span=(15, 17), match='to'>
- strings='Fanstuck wants to leave alone alonely'
- pattern=re.compile('to')
- object_search=pattern.search(strings)
- object_search.group()
- #out:'to'
- object_search.start()
- #out:15
- object_search.end()
- #out:17
- object_search.span()
- #out:(15,17)
基础语法格式为:
re.splite(pattern, string, maxsplit=0, flags=0)
参数说明:
pattern匹配的子串来分割string,如果pattern里使用了圆括号,那么被pattern匹配到的串也将作为返回值列表的一部分,maxsplit为最多被分割的字符串个数。
- strings='Fanstuck wants to leave alone alonely'
- re.split(r' ', strings)
- #out:['Fanstuck', 'wants', 'to', 'leave', 'alone', 'alonely']
- strings='Fanstuck wants to leave alone alonely'
- re.split(r' ', strings,maxsplit=2)
- #out:['Fanstuck', 'wants', 'to leave alone alonely']
- strings='Fanstuck wants to leave alone alonely'
- re.split(r'( )', strings,maxsplit=2)
- #out:['Fanstuck', ' ', 'wants', ' ', 'to leave alone alonely']
re.match()、re.search()成功匹配的话都会返回一个Match对象,它包含了关于此次匹配的信息,可以使用Match提供的属性或方法来获取这些信息;Pattern对象对象由re.compile()生成,而且方法用处也是一样的。
- strings='Fanstuck wants to leave alone alonely'
- pattern=re.compile('to')
- object_search=pattern.search(strings)
- object_search.string
- #out:'Fanstuck wants to leave alone alonely'
- object_search.re
- #out:re.compile(r'to', re.UNICODE)
- object_search.pos
- #out:0 (开始匹配的位置)
- object_search.endpos
- #out:37(结束匹配的位置)
- object_search.lastindex
- #out:None
- object_search.lastgroup
- #out:None
- object_search.groupdict()
- #out:{}
- object_search.group()
- #out:'to'
- object_search.start()
- #out:15
- object_search.end()
- #out:17
- object_search.span()
- #out:(15,17)
正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
待会我们会用到re库中的函数还进行字符匹配,这里可以通过一个例子先看一下语法:
- import re
- a = "abbbbbccccd"
- b = re.findall('ab+c+d',a)
- print(b)
['abbbbbccccd']
构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。
正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。
普通字符串,上述例子基本用的都是普通字符串。这里我们用findall()函数来演示更好:
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('alone',strings))
['alone', 'alone']
匹配 [...] 中的所有字符:
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('[alone]',strings))
['a', 'n', 'a', 'n', 'o', 'l', 'e', 'a', 'e', 'a', 'l', 'o', 'n', 'e', 'a', 'l', 'o', 'n', 'e', 'l']
匹配除了 [^...] 中字符的所有字符
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('[^alone]',strings))
['F', 'u', 'c', 'k', ' ', ' ', 'o', ' ', 'l', 'e', 'v', 'e', ' ', 'l', 'o', 'e', ' ', 'l', 'o', 'e', 'l', 'y']
[A-Z] 表示一个区间,匹配所有大写字母,[a-z] 表示所有小写字母。
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('[^A-F]',strings))
['a', 'n', 's', 't', 'u', 'c', 'k', ' ', 'w', 'a', 'n', 't', 's', ' ', 't', 'o', ' ', 'l', 'e', 'a', 'v', 'e', ' ', 'a', 'l', 'o', 'n', 'e', ' ', 'a', 'l', 'o', 'n', 'e', 'l', 'y']
匹配除换行符(\n、\r)之外的任何单个字符,相等于 [^\n\r]。
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('.',strings))
['F', 'a', 'n', 's', 't', 'u', 'c', 'k', ' ', 'w', 'a', 'n', 't', 's', ' ', 't', 'o', ' ', 'l', 'e', 'a', 'v', 'e', ' ', 'a', 'l', 'o', 'n', 'e', ' ', 'a', 'l', 'o', 'n', 'e', 'l', 'y']
匹配所有。\s 是匹配所有空白符,包括换行,\S 非空白符,不包括换行。
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('[\s\S]',strings))
['F', 'a', 'n', 's', 't', 'u', 'c', 'k', ' ', 'w', 'a', 'n', 't', 's', ' ', 't', 'o', ' ', 'l', 'e', 'a', 'v', 'e', ' ', 'a', 'l', 'o', 'n', 'e', ' ', 'a', 'l', 'o', 'n', 'e', 'l', 'y']
匹配字母、数字、下划线。等价于 [A-Za-z0-9_]
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('\w',strings))
['F', 'a', 'n', 's', 't', 'u', 'c', 'k', 'w', 'a', 'n', 't', 's', 't', 'o', 'l', 'e', 'a', 'v', 'e', 'a', 'l', 'o', 'n', 'e', 'a', 'l', 'o', 'n', 'e', 'l', 'y']
非打印字符也可以是正则表达式的组成部分。下表列出了表示非打印字符的转义序列:
匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
匹配一个换页符。等价于 \x0c 和 \cL。
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('\f',strings))
匹配一个换行符。等价于 \x0a 和 \cJ。
- strings='Fanstuck \n \
- wants to leave \
- alone alonely'
- print(re.findall('\n',strings))
- print(strings)
['\n'] Fanstuck wants to leave alone alonely
匹配一个回车符。等价于 \x0d 和 \cM。
- strings='\r Fanstuck \r \
- wants to leave\r \
- alone alonely'
- print(re.findall('\r',strings))
- print(strings)
['\r', '\r', '\r'] alone alonelye
匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('\s',strings))
[' ', ' ', ' ', ' ', ' ']
匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('\S',strings))
['F', 'a', 'n', 's', 't', 'u', 'c', 'k', 'w', 'a', 'n', 't', 's', 't', 'o', 'l', 'e', 'a', 'v', 'e', 'a', 'l', 'o', 'n', 'e', 'a', 'l', 'o', 'n', 'e', 'l', 'y']
匹配一个制表符。等价于 \x09 和 \cI。
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('\t',strings))
没写啥制表符固为空。
匹配一个垂直制表符。等价于 \x0b 和 \cK。
所谓特殊字符,就是一些有特殊含义的字符,如上面说的 runoo*b 中的 *,简单的说就是表示任何字符串的意思。如果要查找字符串中的 * 符号,则需要对 * 进行转义,即在其前加一个 \,runo\*ob 匹配字符串 runo*ob。
许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须首先使字符"转义",即,将反斜杠字符\ 放在它们前面。下表列出了正则表达式中的特殊字符:
匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与 \n 或 \r 之前的位置匹配。则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,请使用 \$。
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall(' alone alonely$',strings))
[' alone alonely']
标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 。
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('(Fan\w{2,3}ck)',strings))
['Fanstuck']
匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('(Fan\w*ck)',strings))
['Fanstuck']
匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('(alone)+',strings))
['alone', 'alone']
匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('Fa.s.u.k',strings))
['Fanstuck']
标记一个中括号表达式的开始。要匹配 [,请使用 \[。
匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。
这里要注意一下贪婪模式和非贪婪模式。
贪婪模式:尽可能多的去匹配数据,表现为\w后面加某个元字符,例如\w*:
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('F\w*',strings))
['Fanstuck']
非贪婪模式:尽可能少的去匹配数据,表现为\w后面加?,例如\w?
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('F\w?',strings))
['Fa']
将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\",而 '\(' 则匹配 "("。
- strings='alone alonely'
- print(re.findall('^alone',strings))
['alone']
标记限定符表达式的开始。要匹配 {,请使用 \{。
指明两项之间的一个选择。要匹配 |,请使用 \|。
限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种。
正则表达式的限定符有:
上述已作展示
上述已作展示
上述已作展示
n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('Fan\w{2}uck',strings))
n 是一个非负整数。至少匹配n 次。贪婪
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('Fan\w{1,}uck',strings))
['Fanstuck']
m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。贪婪
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('^(\w{2,8}\s*\w{2,8})+',strings))a
['Fanstuck wants']
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('^Fanstuck[(\w{2,8}\s*)+]+ly',strings))
['Fanstuck wants to leave alone alonely']
* 和 + 限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个 ? 就可以实现非贪婪或最小匹配。
上述已经演示
上述已经演示
匹配一个单词边界,即字与空格间的位置。
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall(r'\balone\b',strings))
['alone']
和 ’/b’ 相反,它只匹配非边界的字符。
- strings='Fanstuck wants to leave alone alonely'
- print(re.findall('alone\\Bly',strings))
['alonely']
以上就是本期全部内容。我是fanstuck ,有问题大家随时留言讨论 ,我们下期见。