开放的编程资料库

当前位置:我爱分享网 > Python教程 > 正文

Python 正则表达式

Python正则表达式教程展示了如何在Python中使用正则表达式。对于Python中的正则表达式,我们使用re模块。

正则表达式用于文本搜索和更高级的文本操作。正则表达式是内置工具,例如grep、sed、文本编辑器(例如vi、emacs)以及编程语言(例如Tcl、Perl和Python)。

Pythonre模块

在Python中,re模块提供了正则表达式匹配操作。

模式是一个正则表达式,它定义了我们正在搜索或操作的文本。它由文本文字和元字符组成。该模式是使用compile函数编译的。因为正则表达式通常包含特殊字符,所以建议使用原始字符串。(原始字符串前面有r个字符。)这样,字符在编译为模式之前不会被解释。

编译模式后,我们可以使用其中一个函数将模式应用于文本字符串。这些函数包括matchsearchfindfinditer

正则表达式

下表显示了一些基本的正则表达式:

正则表达式 含义
. 匹配任何单个字符。
? 匹配前面的元素一次或根本不匹配.
+ 匹配前面的元素一次或多次。
* 匹配前面的元素零次或多次。
^ 匹配字符串中的起始位置。
$ 匹配字符串中的结束位置.
| 交替运算符。
[abc] 匹配a或b,或c。
[a-c] 范围;匹配a或b,或c。
[^abc] 否定,匹配除a或b以外的所有内容,或c。
\s 匹配空白字符。
code>\w 匹配一个单词字符;相当于[a-zA-Z_0-9]

正则表达式函数

我们寻找与正则表达式函数的匹配项。

Function Description
匹配 判断RE是否匹配字符串开头
fullmatch 判断是否RE匹配整个字符串。
search 扫描一个字符串,寻找这个RE所在的任何位置匹配。
findall 查找RE匹配的所有子字符串,并将它们作为列表返回。
finditer 查找RE匹配的所有子字符串,并将它们作为迭代器返回。
split 按RE模式拆分字符串。

matchfullmatchsearch函数如果成功则返回一个匹配对象。否则,它们返回None

匹配函数

如果字符串开头的零个或多个字符与正则表达式模式匹配,则match函数返回一个匹配对象。

#!/usr/bin/python

import re

words = ('book', 'bookworm', 'Bible', 
    'bookish','cookbook', 'bookstore', 'pocketbook')

pattern = re.compile(r'book')

for word in words:

    if re.match(pattern, word):
        print(f'The {word} matches')

在示例中,我们有一个单词元组。编译后的模式将在每个单词中查找“book”字符串。

pattern = re.compile(r'book')

使用compile函数,我们创建了一个模式。正则表达式是一个原始字符串,由四个普通字符组成。

for word in words:

    if re.match(pattern, word):
        print(f'The {word} matches')

我们遍历元组并调用match函数。它将模式应用到单词上。match函数在字符串开头有匹配项时返回一个匹配对象。如果没有匹配项则返回None

$ ./match_fun.py 
The book matches 
The bookworm matches 
The bookish matches 
The bookstore matches 

元组中的四个单词与模式匹配。请注意,不以“书”字词开头的单词不匹配。为了也包括这些词,我们使用search功能。

全匹配函数

fullmatch函数看起来完全匹配。

#!/usr/bin/python

import re

words = ('book', 'bookworm', 'Bible', 
    'bookish','cookbook', 'bookstore', 'pocketbook')

pattern = re.compile(r'book')

for word in words:

    if re.fullmatch(pattern, word):
        print(f'The {word} matches')

在示例中,我们使用fullmatch函数来查找确切的“book”字词。

$ ./fullmatch_fun.py 
The book matches

只有一个匹配。

搜索功能

search函数查找正则表达式模式产生匹配项的第一个位置。

#!/usr/bin/python

import re

words = ('book', 'bookworm', 'Bible', 
    'bookish','cookbook', 'bookstore', 'pocketbook')

pattern = re.compile(r'book')

for word in words:

    if re.search(pattern, word):
        print(f'The {word} matches')   

在示例中,我们使用search函数来查找“book”字词。

$ ./search_fun.py 
The book matches 
The bookworm matches 
The bookish matches 
The cookbook matches 
The bookstore matches 
The pocketbook matches 

这次食谱和钱包单词也包括在内。

点元字符

点(.)元字符代表文本中的任何单个字符。

#!/usr/bin/python

import re

words = ('seven', 'even', 'prevent', 'revenge', 'maven', 
    'eleven', 'amen', 'event')

pattern = re.compile(r'.even')

for word in words:
    if re.match(pattern, word):
        print(f'The {word} matches')

在示例中,我们有一个包含八个单词的元组。我们在每个单词上应用包含点元字符的模式。

pattern = re.compile(r'.even')

点代表文本中的任何单个字符。该字符必须存在。

$ ./dot_meta.py 
The seven matches 
The revenge matches 

两个词符合模式:七和复仇。

问号元字符

问号(?)元字符是与前一个元素零次或一次匹配的量词。

#!/usr/bin/python

import re

words = ('seven', 'even','prevent', 'revenge', 'maven', 
    'eleven', 'amen', 'event')

pattern = re.compile(r'.?even')

for word in words:

    if re.match(pattern, word):
        print(f'The {word} matches')

在示例中,我们在点字符后添加了一个问号。这意味着在模式中我们可以有一个任意字符,也可以没有任何字符。

$ ./question_mark_meta.py 
The seven matches 
The even matches 
The revenge matches 
The event matches 

这一次,除了七和复仇之外,even和event的词组也是如此。

锚点

锚匹配给定文本中字符的位置。使用^锚点时,匹配必须出现在字符串的开头,而使用$锚点时,匹配必须出现在字符串的末尾。

#!/usr/bin/python

import re

sentences = ('I am looking for Jane.',
    'Jane was walking along the river.',
    'Kate and Jane are close friends.')

pattern = re.compile(r'^Jane')

for sentence in sentences:
    
    if re.search(pattern, sentence):
        print(sentence)

在示例中,我们有三个句子。搜索模式是^Jane。该模式检查“Jane”字符串是否位于文本的开头。Jane\.将在句子末尾查找“Jane”。

精确匹配

可以使用fullmatch函数或将术语放在锚点之间:^和$来执行精确匹配。

#!/usr/bin/python

import re

words = ('book', 'bookworm', 'Bible', 
    'bookish','cookbook', 'bookstore', 'pocketbook')

pattern = re.compile(r'^book$')

for word in words:

    if re.search(pattern, word):
        print(f'The {word} matches')  

在示例中,我们寻找与“书”字词完全匹配的词。

$ ./exact_match.py 
The book matches

字符类

字符类定义了一组字符,其中任何一个字符都可以出现在输入字符串中才能成功匹配。

#!/usr/bin/python

import re

words = ('a gray bird', 'grey hair', 'great look')

pattern = re.compile(r'gr[ea]y')

for word in words:

    if re.search(pattern, word):
        print(f'{word} matches') 

在示例中,我们使用字符类来包含灰色和灰色词。

pattern = re.compile(r'gr[ea]y')

[ea]类允许在模式中使用’e’或’a’字符。

命名字符类

有一些预定义的字符类。\s匹配一个空白字符[\t\n\t\f\v]\d匹配一个数字[0-9],以及\w一个单词字符[a-zA-Z0-9_]

#!/usr/bin/python

import re

text = 'We met in 2013. She must be now about 27 years old.'

pattern = re.compile(r'\d+')

found = re.findall(pattern, text)

if found:
    print(f'There are {len(found)} numbers')   

在示例中,我们计算文本中的数字。

pattern = re.compile(r'\d+')

\d+模式在文本中查找任意数量的数字集。

found = re.findall(pattern, text)

使用findall方法,我们查找文本中的所有数字。

$ ./named_character_classes.py 
There are 2 numbers

不区分大小写的匹配

默认情况下,模式的匹配是区分大小写的。通过将re.IGNORECASE传递给compile函数,我们可以使其不区分大小写。

#!/usr/bin/python

import re

words = ('dog', 'Dog', 'DOG', 'Doggy')

pattern = re.compile(r'dog', re.IGNORECASE)

for word in words:
    if re.match(pattern, word):
        print(f'{word} matches')

在示例中,我们将模式应用于单词而不考虑大小写。

$ ./case_insensitive.py 
dog matches
Dog matches
DOG matches
Doggy matches

所有四个词都匹配模式。

交替

交替运算符|创建一个有多个选项的正则表达式。

#!/usr/bin/python

import re

words = ("Jane", "Thomas", "Robert",
    "Lucy", "Beky", "John", "Peter", "Andy")

pattern = re.compile(r'Jane|Beky|Robert')

for word in words:
    
    if re.match(pattern, word):
        print(word)

列表中有八个名字。

pattern = re.compile(r'Jane|Beky|Robert')

此正则表达式查找“​​Jane”、“Beky”或“Robert”字符串。

查找器功能

finditer函数返回一个迭代器,该迭代器为字符串中的模式的所有非重叠匹配生成匹配对象。

#!/usr/bin/python

import re

text = 'I saw a fox in the wood. The fox had red fur.'

pattern = re.compile(r'fox')

found = re.finditer(pattern, text)

for item in found:

    s = item.start()
    e = item.end()
    print(f'Found {text[s:e]} at {s}:{e}')

在示例中,我们在文本中搜索“fox”一词。我们遍历找到的匹配项的迭代器并打印它们及其索引。

s = item.start()
e = item.end()

startend函数分别返回开始和结束索引。

$ ./finditer_fun.py 
Found fox at 8:11
Found fox at 29:32

捕获组

捕获组是一种将多个字符视为一个单元的方法。它们是通过将字符放在一组圆括号内创建的。例如,(book)是包含“b”、“o”、“o”、“k”字符的单个组。

捕获组技术使我们能够找出字符串中与常规模式匹配的部分。

#!/usr/bin/python

import re

content = '''<p>The <code>Pattern</code> is a compiled
representation of a regular expression.</p>'''

pattern = re.compile(r'(</?[a-z]*>)')

found = re.findall(pattern, content)

for tag in found:
    print(tag)

代码示例通过捕获一组字符来打印提供的字符串中的所有HTML标记。

found = re.findall(pattern, content)

为了找到所有标签,我们使用findall方法。

$ ./capturing_groups.py 
<p>
<code>
</code>
</p>

我们找到了四个HTML标签。

Python正则表达式电子邮件示例

在下面的示例中,我们创建了一个用于检查电子邮件地址的正则表达式模式。

#!/usr/bin/python

import re

emails = ("luke@gmail.com", "andy@yahoocom", 
    "34234sdfa#2345", "f344@gmail.com")

pattern = re.compile(r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+\.[a-zA-Z.]{2,18}$')

for email in emails:

    if re.match(pattern, email):
        print(f'{email} matches')
    else:
        print(f'{email} does not match')

这个例子提供了一种可能的解决方案。

pattern = re.compile(r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+\.[a-zA-Z.]{2,18}$')    

第一个^和最后一个$字符提供精确的模式匹配。模式前后不允许有任何字符。邮件分为五个部分。第一部分是本地部分。这通常是公司名称、个人名称或昵称。[a-zA-Z0-9._-]+列出了所有可能的字符,我们可以在本地部分使用。它们可以使用一次或多次。

第二部分由文字@字符组成。第三部分是领域部分。它通常是电子邮件提供商的域名,例如Yahoo或Gmail。[a-zA-Z0-9-]+是一个字符类,提供了可以在域名中使用的所有字符。+量词允许使用这些字符中的一个或多个。

第四部分是点字符。它前面有转义字符(\)以获得文字点。

最后一部分是顶级域:[a-zA-Z.]{2,18}。顶级域可以有2到18个字符,例如sk、net、信息、旅行、清洁、旅行保险。最大长度可以是63个字符,但现在大多数域都短于18个字符。还有一个点字符。这是因为一些顶级域有两个部分;例如co.uk。

$ ./emails.py 
luke@gmail.com matches
andy@yahoocom does not match
34234sdfa#2345 does not match
f344@gmail.com matches

在本章中,我们介绍了Python中的正则表达式。

阅读Python教程或列出所有Python教程。

未经允许不得转载:我爱分享网 » Python 正则表达式

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏