简述
正则表达式 (RegEx) 是一个特殊的字符序列,它使用搜索模式来查找一个字符串或一组字符串。它可以通过将文本与特定模式进行匹配来检测文本的存在与否,还可以将模式拆分为一个或多个子模式。Python提供了一个re模块,支持在Python中使用正则表达式。它的主要功能是提供搜索,其中它采用正则表达式和字符串。在这里,它要么返回第一个匹配项,要么不返回任何匹配项。
例子:
import re
s = 'GeeksforGeeks: A computer science portal for geeks'
match = re.search(r'portal', s)
print('Start 索引位置:', match.start())
print('End 索引位置:', match.end())
输出
上面的代码给出了字符串门户的起始索引和结束索引。
注意: 这里的r字符(r’portal’)代表原始,而不是正则表达式。原始字符串与常规字符串略有不同,它不会将 \ 字符解释为转义字符。这是因为正则表达式引擎使用 \ 字符来实现其自身的转义目的。
在开始使用Python正则表达式模块之前,让我们看看如何使用元字符或特殊序列实际编写正则表达式。
普通字符
正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。
元字符
为了理解RE方法,元字符是非常有用的,重要的,并将用于模块re的功能。以下是元字符列表。
元字符 | 描述 |
---|
\ | 用于去掉字符后面的特殊含义 | [] | 表示字符类 | ^ | 匹配开头 | $ | 匹配结尾 | . | 匹配除换行符以外的任何字符 | | | 表示 OR(与由它分隔的任何字符匹配。 | ? | 匹配零次或一次匹配 | * | 任意发生次数(包括 0 次出现) | + | 一个或多个实例 | {} | 指示要匹配的前面正则表达式的出现次数。 | () | 将一组正则表达式括起来 |
让我们详细讨论这些元字符中的每一个
\ 反斜杠
反斜杠 \ 确保不会以特殊方式处理字符。这可以被认为是一种转义元字符的方法。例如,如果要在字符串中搜索 dot(.),那么您会发现 dot(.) 将被视为一个特殊字符,就像元字符之一一样(如上表所示)。因此,对于这种情况,我们将在 dot(.) 之前使用反斜杠(\),以便它将失去其特性。请参阅下面的示例以更好地理解。
例:
import re
s = 'geeks.forgeeks'
# without using \
match = re.search(r'.', s)
print(match)
# using \
match = re.search(r'.', s)
print(match)
输出:
[] 方括号
方括号 [] 表示由我们希望匹配的一组字符组成的字符类。例如,字符类 [abc] 将匹配任何单个 a、b 或 c。
我们还可以使用方括号内的 – 指定字符范围。例如
[0, 3] 为样品作为[a-c] 与 [abc] 相同
我们还可以使用插入符号 ^ 反转字符类。例如
[^0-3] 表示除 0、1、2 或 3 以外的任何数字[^a-c] 表示除 a、b 或 c 以外的任何字符
^
插入记号^ 符号与字符串的开头匹配,即检查字符串是否以给定字符开头。例如——
^g 将检查字符串是否以 g 开头,例如geeks, globe, girl, getc等。^ge 将检查字符串是否以 ge 开头,例如 geeks、geeksforgeeks 等。
$ 美元
Dollar$ 符号与字符串的末尾匹配,即检查字符串是否以给定字符结尾。例如——
s$ 将检查以 geeks、ends、s 等结尾的字符串。ks$ 将检查以 ks 结尾的字符串,例如 geeks、geeksforgeeks、ks 等。
. 点
点. 符号仅匹配除换行符 \n 之外的单个字符。例如——
a.b 将检查在点的位置包含任何字符的字符串,例如acb,acbd,abbb等.. 将检查字符串是否包含至少2个字符
| 或
| 符号用作 or 运算符,这意味着它检查字符串中是否存在 or 符号之前或之后的模式。例如——
a|b 将匹配任何包含 a 或 b 的字符串,如 acd、bcd、abcd 等。
? 问号
问号? 检查正则表达式中问号前面的字符串是否至少出现一次或根本不出现。例如——
ab?c 将匹配字符串 ac、acb、dabc,但不会匹配 abbc,因为有两个 b。同样,它不会与 abdc 匹配,因为 b 后面没有 c。
* 星星
星号 * 符号匹配 * 符号前面的正则表达式的零个或多个匹配项。例如——
ab*c 将匹配字符串 ac、abc、abbbc、dabc 等,但不会匹配 abdc,因为 b 后面没有 c。
+ 加号
加号 + 匹配 + 符号前面的正则表达式的一个或多个匹配项。例如——
ab+c 将匹配字符串 abc、abbc、dabc,但不会匹配 ac,abdc 因为 ac 中没有 b,而 abdc 后面没有 c。
{m, n} 大括号
{} 匹配正则表达式之前的任何重复,从 m 到 n(包括 m 和 n)。例如——
a{2, 4} 将匹配字符串 aaab、baaaac、gaad,但不会匹配 abc、bc 等字符串,因为在这两种情况下只有一个 a 或没有 a。
(<正则表达式>) – 组
组符号用于对子模式进行分组。例如——
(a|b)cd 将匹配 acd、abcd、gacd 等字符串。
特殊序列
特殊序列与字符串中的实际字符不匹配,而是告诉搜索字符串中必须发生匹配的特定位置。它使编写常用模式变得更加容易。
特殊序列列表
特殊序列 | 描述 | 例子 | |
---|
\A | 如果字符串以给定字符开头,则匹配 | \A for | for geeks | \b | 如果单词以给定字符开头或结尾,则匹配。\b(字符串)将检查单词的开头,(字符串)\b 将检查单词的结尾 | \b ge | geeks | \B | 它与 \b 相反,即字符串不应以给定的正则表达式开头或结尾 | \B ge | forge | \d | 配任何十进制数字,这等效于设置类 [0-9] | \d | 123 | \D | 匹配任何非数字字符,这等效于集合类 [^0-9] | \D | geeks | \s | 匹配任何空格字符 | \s | gee ks | \S | 匹配任何非空格字符 | \S | a bd | \w | 匹配任何字母数字字符,这等效于类 [a-zA-Z0-9_] | \w | 123 | \W | 匹配任何非字母数字字符。 | \W | >$ | \Z | 如果字符串以给定正则表达式结尾,则匹配 | ab\Z | abcdab |
Python 中的正则表达式模块
Python有一个名为re的模块,用于Python中的正则表达式。我们可以使用 import 语句导入此模块。
例: 在 Python 中导入 re 模块
import re
让我们看看这个模块提供的各种函数,以便在Python中使用正则表达式。
re.findall()
将字符串中模式的所有非重叠匹配项作为字符串列表返回。从左到右扫描字符串,并按找到的顺序返回匹配项。
例: 查找模式的所有匹配项
# findall()
import re
# 示例文本字符串,其中正则表达式
# 已搜索。
string = """Hello my Number is 123456789 and my friend's number is 987654321"""
# 用于查找数字的示例正则表达式。
regex = '\d+'
match = re.findall(regex, string)
print(match)
输出
re.compile()
正则表达式被编译成模式对象,这些对象具有用于各种操作的方法,例如搜索模式匹配或执行字符串替换。
示例 1:
import re
# compile()创建正则表达式
# 字符类【a-e】,
# 这相当于[abcde]。
# 类[abcde]将与字符串匹配
# 'a', 'b', 'c', 'd', 'e'.
p = re.compile('[a-e]')
# findall()搜索正则表达式
# 并在找到后返回列表
print(p.findall("Aye, said Mr. Gibenson Stark"))
输出:
了解输出:
- 第一次出现的是“Aye”中的“e”,而不是“A”,因为它区分大小写。
- 下一个出现点是“said”中的“a”,然后是“said”中的“d”,然后是“Gibenson”中的“b”和“e”,最后一个“a”与“Stark”匹配。
- 元字符反斜杠’‘具有非常重要的作用,因为它发出各种序列的信号。如果要使用反斜杠而不使用其作为元字符的特殊含义,请使用’\’
re.split()
按字符或模式的出现次数拆分字符串,找到该模式后,字符串中的其余字符将作为结果列表的一部分返回。
语法:
re.split(pattern, string, maxsplit=0, flags=0)
第一个参数,pattern 表示正则表达式,string 是给定的字符串,其中将搜索模式并进行拆分,如果未提供maxsplit ,则认为maxsplit 为零“0 ”,如果提供了任何非零值,则最多发生许多拆分。如果 maxsplit = 1, 则字符串将仅拆分一次,从而生成长度为 2 的列表。标志非常有用,可以帮助缩短代码,它们不是必需的参数,例如:flags = re。IGNORECASE ,在此拆分中,大小写,即小写或大写将被忽略。
示例 1:
from re import split
# '\W+' 表示非字母数字字符
# 或查找时的字符组 ','
# 或空白' ', split(), 拆分从该点开始的字符串
print(split('\W+', 'Words, words , Words'))
print(split('\W+', "Word's words Words"))
# 这里 ':', ' ' ,',' 因此不是字母数字,
# 发生拆分的点
print(split('\W+', 'On 12th Jan 2016, at 11:02 AM'))
# '\d+' 表示数字字符或一组
# 字符拆分发生在“12”, '2016',
# '11', '02' only
print(split('\d+', 'On 12th Jan 2016, at 11:02 AM'))
输出:
示例 2:
import re
# 拆分只会在“12”处发生一次,返回的列表长度为2
#
print(re.split('\d+', 'On 12th Jan 2016, at 11:02 AM', 1))
# 'Boy' and 'boy' 当 flags = re.IGNORECASE 时,将被视为相同。忽略案例
print(re.split('[a-f]+', 'Aey, Boy oh boy, come here', flags=re.IGNORECASE))
print(re.split('[a-f]+', 'Aey, Boy oh boy, come here'))
输出:
re.sub()
函数中的“sub”代表SubString,在给定的字符串(第3个参数)中搜索某个正则表达式模式,并在发现子字符串模式被repl(第2个参数)替换后,计数检查并保持这种情况发生的次数。
语法:
re.sub(pattern, repl, string, count=0, flags=0)
示例 1:
import re
# 正则表达式模式“ub”匹配“Subject”和“Uber”处的字符串。视情况而定
# 已忽略,使用标记“ub”应在匹配时与字符串匹配两次,
# “Subject”中的“ub”替换为“~*”,而“Uber”中的“ub”替换为“ub”。
print(re.sub('ub', '~*', 'Subject has Uber booked already', flags=re.IGNORECASE))
# 考虑到区分大小写,“Uber”中的“Ub”将不会被替换。
print(re.sub('ub', '~*', 'Subject has Uber booked already'))
# 由于count的值为1,因此发生替换的最大次数为1
print(re.sub('ub', '~*', 'Subject has Uber booked already',
count=1, flags=re.IGNORECASE))
# 模式前的“r”表示RE,\s表示字符串的开始和结束。
print(re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam',
flags=re.IGNORECASE))
输出
re.subn()
subn() 在所有方面都与 sub() 相似,除了提供输出的方式。它返回一个元组,其中包含替换和新字符串的总数,而不仅仅是字符串。
语法:
re.subn(pattern, repl, string, count=0, flags=0)
例:
import re
print(re.subn('ub', '~*', 'Subject has Uber booked already'))
t = re.subn('ub', '~*', 'Subject has Uber booked already',
flags=re.IGNORECASE)
print(t)
print(len(t))
# 这将提供与sub()相同的输出
print(t[0])
输出
re.escape()
返回所有非字母数字反斜杠的字符串,如果要匹配可能包含正则表达式元字符的任意文本字符串,这将非常有用。
语法:
re.escape(string)
例:
import re
# escape()返回在每个非字母数字字符之前带有反斜杠“\”的字符串
# 仅在第一种情况下为“”,在第二种情况下为非字母数字“”,插入符号“^”、“-”、“[]”、“\”
# 不是字母数字
print(re.escape("This is Awesome even 1 AM"))
print(re.escape("I Asked what is this [a-9], he said \t ^WoW"))
输出
re.search()
此方法返回 None(如果模式不匹配),或返回 re。匹配对象包含有关字符串的匹配部分的信息。此方法在第一次匹配后停止,因此这最适合测试正则表达式而不是提取数据。
例: 搜索模式的出现次数
import re
# 让我们使用正则表达式匹配日期字符串,格式为月份名称后跟天数
regex = r"([a-zA-Z]+) (\d+)"
match = re.search(regex, "I was born on June 24")
if match != None:
# 当表达式“([a-zA-Z]+)(\d+)与日期字符串匹配时,我们到达这里。
# 这将打印[14,21],因为它在索引14处匹配,在21处结束。
print("Match at index %s, %s" % (match.start(), match.end()))
# 我们使用group()方法获取所有匹配项
# 捕获的组。这些组包含匹配的值。
# 特别是:
# 匹配。group(0)始终返回完全匹配的字符串
# 匹配。group(1)匹配。group(2)。。。返回捕获
# 在输入字符串中按从左到右的顺序分组
# 匹配。group()等效于match。组(0)
# 所以这将打印“6月24日”
print("Full match: %s" % (match.group(0)))
# 所以这将打印“June”
print("Month: %s" % (match.group(1)))
# 所以这将打印 "24"
print("Day: %s" % (match.group(2)))
else:
print("The regex pattern does not match.")
输出
匹配对象
Match 对象包含有关搜索和结果的所有信息,如果未找到匹配项,则将返回 None。让我们看一下 match 对象的一些常用方法和属性。
获取字符串和正则表达式
match.re 属性返回传递的正则表达式,match.string 属性返回传递的字符串。
例: 获取匹配对象的字符串和正则表达式
import re
s = "Welcome to GeeksForGeeks"
# 这里x是匹配对象
res = re.search(r"\bG", s)
print(res.re)
print(res.string)
输出
获取匹配对象的索引
- start() 方法返回匹配子字符串的起始索引
- end() 方法返回匹配子字符串的结束索引
- span() 方法返回一个元组,其中包含匹配子字符串的起始索引和结束索引
例: 获取匹配对象的索引
import re
s = "Welcome to GeeksForGeeks"
# 这里x是匹配对象
res = re.search(r"\bGee", s)
print(res.start())
print(res.end())
print(res.span())
输出
获取匹配的子字符串
group() 方法返回模式匹配的字符串部分。请参阅下面的示例以更好地理解。
例: 获取匹配的子字符串
import re
s = "Welcome to GeeksForGeeks"
# 这里x是匹配对象
res = re.search(r"\D{2} t", s)
print(res.group())
输出
参考资料:
https://docs.python.org/2/library/re.html
|