Python 正则表达式
正则表达式是一种特殊的字符序列,帮助您匹配或查找其他字符串或字符串集合,使用模式中保存的特殊语法。正则表达式也被称为regex或regexp,它是一系列定义搜索模式的字符序列。通常,这些模式被用于字符串搜索算法的“查找”或“查找和替换”操作,或用于输入验证。
在数据科学项目中,大规模文本处理需要对文本数据进行操作。正则表达式处理被许多编程语言支持,包括Python。Python的标准库有用于此目的的’re’模块。
由于re模块中定义的大多数函数都使用原始字符串(raw strings)进行操作,因此让我们首先了解什么是原始字符串。
原始字符串
正则表达式使用反斜杠字符(\
)来指示特殊形式或允许使用特殊字符而不会引发其特殊含义。另一方面,Python使用相同字符作为转义字符。因此Python使用原始字符串表示法。
如果字符串在引号符号前加上r或R前缀,则该字符串变为原始字符串。因此’Hello’是一个普通字符串,而r’Hello’是一个原始字符串。
>>> normal="Hello"
>>> print (normal)
Hello
>>> raw=r"Hello"
>>> print (raw)
Hello
在正常情况下,这两者没有区别。然而,当转义字符嵌入在字符串中时,普通字符串实际上会解释转义序列,而原生字符串不会处理转义字符。
>>> normal="Hello\nWorld"
>>> print (normal)
Hello
World
>>> raw=r"Hello\nWorld"
>>> print (raw)
Hello\nWorld
在上面的例子中,当普通字符串被打印时,转义字符\n
会被处理成换行符。然而,由于原生字符串运算符’r’的存在,转义字符的效果不会按照其原意进行转换。
元字符
大多数字母和字符只会匹配它们自己。然而,一些字符是特殊的元字符,它们不会匹配它们自己。元字符是具有特殊含义的字符,类似于通配符中的*符号。
下面是元字符的完整列表:
. ^ $ * + ? { } [ ] \ | ( )
方括号符号[和]表示您希望匹配的一组字符。字符可以单独列出,也可以通过使用“-”来表示字符范围。
序号 | 元字符及描述 |
---|---|
1 | [abc] 匹配字符a,b或c中的任意一个 |
2 | [a-c] 使用一个范围来表示相同的字符集合 |
3 | [a-z] 仅匹配小写字母 |
4 | [0-9] 仅匹配数字 |
5 | ^ 补集,与[ ] 中的字符集合不匹配。[^5] 将匹配除了5 以外的任意字符。 |
\
是一个转义元字符。 当紧跟着各种字符时,它形成各种特殊序列。 如果您需要匹配[
或\
,可以在它们之前加上一个反斜杠来删除它们的特殊含义:\\[
或\\\
。
以’\’开头的特殊序列代表的预定义字符集如下所示 −
序号 | 元字符及描述 |
---|---|
1 | \d 匹配任何十进制数字;相当于类 [0-9] 。 |
2 | \D 匹配任何非数字字符;相当于类 [^0-9] 。 |
3 | \s 匹配任何空白字符;相当于类 [\t\n\r\f\v] 。 |
4 | \S 匹配任何非空白字符;相当于类 [^\t\n\r\f\v] 。 |
5 | \w 匹配任何字母数字字符;相当于类 [a-zAZ0-9_] 。 |
6 | \W 匹配任何非字母数字字符;相当于类 [^a-zAZ0-9_] 。 |
7 | . 匹配除换行符 \n 外的任何单个字符。 |
8 | ? 匹配左侧模式的 0 或 1 次出现。 |
9 | + 匹配左侧模式的 1 次或多次出现。 |
10 | * 匹配左侧模式的 0 次或多次出现。 |
11 | \b 单词与非单词之间的边界,/B 与 /b 相反。 |
12 | [..] 匹配方括号中的任何单个字符,[^..] 匹配方括号中没有的任何单个字符。 |
13 | \ 用于具有特殊意义的字符,如 \\. 匹配句点或 \\+ 匹配加号。 |
14 | {n,m} 匹配前面的模式至少 n 次,最多 m 次。 |
15 | a| b 匹配a或者b |
Python的re模块提供了有用的函数,用于查找匹配项,搜索模式,并将匹配的字符串替换为其他字符串等等。
re.match()函数
此函数尝试在字符串的开头使用可选的标志来匹配RE模式。
这是该函数的 语法 :
re.match(pattern, string, flags=0)
下面是参数的描述:
序号 | 参数和描述 |
---|---|
1 | pattern 这是要匹配的正则表达式。 |
2 | String 这是要搜索的字符串,它将在字符串的开头匹配正则表达式。 |
3 | Flags 您可以使用按位与(| )指定不同的标志。这些是在下表中列出的修饰符。 |
re.match函数在匹配成功时返回一个 match 对象,失败时返回 None 。match对象实例包含有关匹配的信息:开始和结束位置、匹配的子字符串等。
match对象的start()方法返回模式在字符串中的起始位置,end()返回结束位置。
如果找不到模式,match对象为None。
我们使用 match 对象的group(num)或groups()函数来获取匹配的表达式。
序号 | 匹配对象方法和描述 |
---|---|
1 | group(num=0) 此方法返回完整匹配(或特定子组编号) |
2 | groups() 此方法返回元组中的所有匹配子组(如果没有则为空) |
示例
import re
line = "Cats are smarter than dogs"
matchObj = re.match( r'Cats', line)
print (matchObj.start(), matchObj.end())
print ("matchObj.group() : ", matchObj.group())
它会产生以下输出。
0 4
matchObj.group() : Cats
re.search()函数
该函数在字符串中搜索正则表达式模式的第一个匹配项,可以使用可选参数flags。
函数的语法如下:
re.search(pattern, string, flags=0)
这里是参数的描述 –
序号 | 参数与说明 |
---|---|
1 | pattern 这是要匹配的正则表达式。 |
2 | string 这是要搜索的字符串,在字符串中的任何位置匹配模式。 |
3 | flags 您可以使用按位或(| )指定不同的标志。这些是在下表中列出的修饰符。 |
re.search函数在成功时返回一个 match 对象,失败时返回 none 。我们可以使用 match 对象的group(num)或groups()函数来获取匹配的表达式。
序号 | Match 对象方法和描述 |
---|---|
1 | group(num=0) 这个方法返回整个匹配(或特定子组的 num) |
2 | groups() 这个方法返回元组中的所有匹配子组(如果没有则返回空) |
例子
import re
line = "Cats are smarter than dogs"
matchObj = re.search( r'than', line)
print (matchObj.start(), matchObj.end())
print ("matchObj.group() : ", matchObj.group())
它将产生以下 输出 −
17 21
matchObj.group() : than
匹配与搜索
Python提供了两种基于正则表达式的原始操作:match只在字符串的开头检查匹配,而search在字符串的任何位置检查匹配(这是Perl的默认行为)。
示例
import re
line = "Cats are smarter than dogs";
matchObj = re.match( r'dogs', line, re.M|re.I)
if matchObj:
print ("match --> matchObj.group() : ", matchObj.group())
else:
print ("No match!!")
searchObj = re.search( r'dogs', line, re.M|re.I)
if searchObj:
print ("search --> searchObj.group() : ", searchObj.group())
else:
print ("Nothing found!!")
当上述代码被执行时,它会产生以下 输出 –
No match!!
search --> matchObj.group() : dogs
re.findall() 函数
findall() 函数返回字符串中与模式匹配的所有非重叠项,以列表形式返回字符串或元组。字符串从左到右进行扫描,匹配项按照发现的顺序返回。结果中包含空匹配项。
语法
re.findall(pattern, string, flags=0)
参数
序号 | 参数和描述 |
---|---|
1 | pattern 这是要匹配的正则表达式。 |
2 | string 这是要在字符串中搜索匹配模式的字符串。 |
3 | flags 您可以使用按位或(| )来指定不同的标志。这些是在下表中列出的修饰符。 |
示例
import re
string="Simple is better than complex."
obj=re.findall(r"ple", string)
print (obj)
它将产生以下 输出 –
['ple', 'ple']
以下代码使用findall()函数获取句子中的单词列表。
import re
string="Simple is better than complex."
obj=re.findall(r"\w*", string)
print (obj)
这将产生以下 输出 −
['Simple', '', 'is', '', 'better', '', 'than', '', 'complex', '', '']
re.sub()函数
使用正则表达式的最重要的re方法之一是sub。
语法
re.sub(pattern, repl, string, max=0)
此方法将字符串中与 RE 模式匹配的所有出现替换为 repl ,除非提供了 max 参数。该方法返回修改后的字符串。
示例
import re
phone = "2004-959-559 # This is Phone Number"
# Delete Python-style comments
num = re.sub(r'#.*$', "", phone)
print ("Phone Num : ", num)
# Remove anything other than digits
num = re.sub(r'\D', "", phone)
print ("Phone Num : ", num)
它将产生以下 输出 –
Phone Num : 2004-959-559
Phone Num : 2004959559
示例
下面的示例使用sub()函数将所有出现的is替换为was单词 –
import re
string="Simple is better than complex. Complex is better than complicated."
obj=re.sub(r'is', r'was',string)
print (obj)
这将产生以下结果:-
Simple was better than complex. Complex was better than complicated.
re.compile()函数
compile()函数将正则表达式模式编译为正则表达式对象,可以使用该对象的match()、search()和其他方法进行匹配。
语法
re.compile(pattern, flags=0)
标志
序号 | 修饰符和说明 |
---|---|
1 | re.I 执行不区分大小写的匹配。 |
2 | re.L 根据当前区域设置解释单词。这种解释影响字母组(\w 和\W )以及单词边界行为(\b 和\B )。 |
3 | re.M 使$匹配行的结束(不仅仅是字符串的结束),并使^匹配任何行的开头(不仅仅是字符串的开头)。 |
4 | re.S 使句点(dot)匹配任何字符,包括换行符。 |
5 | re.U 根据Unicode字符集解释字母。此标志影响\w 、\W 、\b 、\B 的行为。 |
6 | re.X 允许“更简洁”的正则表达式语法。它忽略空格(除了在[] 中或通过反斜杠转义时)并将未转义的#视为注释标记。 |
这个序列-
prog = re.compile(pattern)
result = prog.match(string)
就等同于 –
result = re.match(pattern, string)
使用re.compile()并保存结果的正则表达式对象以便在单个程序中多次使用时更高效。
例子
import re
string="Simple is better than complex. Complex is better than complicated."
pattern=re.compile(r'is')
obj=pattern.match(string)
obj=pattern.search(string)
print (obj.start(), obj.end())
obj=pattern.findall(string)
print (obj)
obj=pattern.sub(r'was', string)
print (obj)
它将产生以下输出:
7 9
['is', 'is']
Simple was better than complex. Complex was better than complicated.
re.finditer() 函数
这个函数返回一个迭代器,在字符串中返回所有非重叠的匹配项的匹配对象。
语法
re.finditer(pattern, string, flags=0)
示例
import re
string="Simple is better than complex. Complex is better than
complicated."
pattern=re.compile(r'is')
iterator = pattern.finditer(string)
print (iterator )
for match in iterator:
print(match.span())
将产生以下输出 −
(7, 9)
(39, 41)
Python正则表达式的用途
查找所有副词
findall()匹配模式的所有出现,而不仅仅是第一个出现像search()一样。例如,如果一个作家想要在一些文本中找到所有副词,他们可以使用findall()方法如下:
import re
text = "He was carefully disguised but captured quickly by police."
obj = re.findall(r"\w+ly\b", text)
print (obj)
它将产生以下输出-
['carefully', 'quickly']
查找以元音字母开头的单词
import re
text = 'Errors should never pass silently. Unless explicitly silenced.'
obj=re.findall(r'\b[aeiouAEIOU]\w+', text)
print (obj)
它将产生以下输出
['Errors', 'Unless', 'explicitly']