网站开发一定找前端么,聊城高新区建设局网站,深圳瑞仕建设公司,云畅网站建设Python11-正则表达式 1.正则表达式简介2.正则表达式常见用法和符号3.正则查找4.re.Match对象与group5.re.compile6.正则表达式修饰符7.正则匹配规则8.正则表达式匹配练习9.正则替换10.贪婪模式和非贪婪模式 1.正则表达式简介
正则表达式#xff08;Regular Expression#x… Python11-正则表达式 1.正则表达式简介2.正则表达式常见用法和符号3.正则查找4.re.Match对象与group5.re.compile6.正则表达式修饰符7.正则匹配规则8.正则表达式匹配练习9.正则替换10.贪婪模式和非贪婪模式 1.正则表达式简介
正则表达式Regular Expression是一种用于匹配、查找和操作文本的工具。它是由一系列字符和特殊字符组成的模式用于描述字符串的特征。
在Python中可以使用内置的re模块来使用正则表达式。re模块提供了一系列函数来进行正则表达式的匹配、查找和替换等操作。 Q将下面的word中的数字取出 word a1b23c456def789number
numbers []
for i, w in enumerate(word):if 0 w 9:number wif i len(word) - 1:numbers.append(number)else:if number ! :numbers.append(number)number
print(numbers)使用正则表达式写法
import reword a1b23c456def789print(re.findall(r\d, word)) # [1, 23, 456, 789]
print(re.sub(r\d, x, word)) # axbxxcxxxdefxxx
print(re.sub(r\d, x, word)) # axbxcxdefx通过上面的例子我们体会到了使用正则表达式对字符串处理的便捷。下面我们将介绍python中正则表达式的使用
2.正则表达式常见用法和符号
匹配字符 普通字符可以直接匹配文本中的普通字符例如 a 匹配字符 “a”。字符类用方括号 [] 表示可以匹配方括号内的任意一个字符。例如 [aeiou] 可以匹配任何一个元音字母。范围类在字符类中使用连字符 - 表示一个范围。例如 [0-9] 可以匹配任意一个数字。预定义字符类有一些预定义的字符类例如 \d 匹配任意一个数字\w 匹配任意一个字母、数字或下划线\s 匹配任意一个空白字符。否定字符类在字符类的开头使用 ^ 表示否定例如 [^0-9] 匹配任意一个非数字字符。 匹配重复 *匹配前面的元素零次或多次。匹配前面的元素一次或多次。?匹配前面的元素零次或一次。{n}匹配前面的元素恰好 n 次。{n,}匹配前面的元素至少 n 次。{n,m}匹配前面的元素至少 n 次且不超过 m 次。 匹配位置 ^匹配输入字符串的开始位置。$匹配输入字符串的结束位置。\b匹配单词的边界。 特殊字符 \转义字符用于转义特殊字符。.匹配除换行符外的任意字符。|匹配两个或多个表达式之一。
对上面常见的符号有个印象下面会使用到。
3.正则查找
python里的正则查找有以下几个方法search、match、fullmatch、findall、finditer
search使用用于在字符串中搜索匹配某个模式的子串。
re.search(pattern, string, flags0)pattern要匹配的正则表达式模式。
string要搜索的字符串。
flags可选用于控制正则表达式的匹配方式的标志。\d表示任意一个数字 匹配前面的元素一次或多次\d就是前面的数字出现一次或多次 匹配前面的元素零次或一次 import reword afd1456b23c32567def346# 3开头的数字
result re.search(r3\d, word)
print(result) # re.Match object; span(11, 16), match32567result re.search(r3\d, word)
print(result) # re.Match object; span(11, 13), match32result re.search(r3\d?, word)
print(result) # re.Match object; span(9, 10), match3需要注意的是re.search()只会返回第一个匹配的子串。如果需要找到所有匹配的子串可以使用re.findall()函数。 match使用用于从字符串的开头开始匹配某个模式。
re.match(pattern, string, flags0)pattern要匹配的正则表达式模式。
string要匹配的字符串。
flags可选用于控制正则表达式的匹配方式的标志。import reword afd1456b23c32567def346# match从字符串的开头匹配
result re.match(r3\d, word)
print(result) # None# a后面没有数字
result re.match(ra\d, word)
print(result) # None# afd后面有数字表示一个或多个
result re.match(rafd\d, word)
print(result) # re.Match object; span(0, 7), matchafd1456需要注意的是re.match()只会从字符串的开头进行匹配。如果需要在整个字符串中查找匹配的子串可以使用re.search()函数或re.findall()函数。 fullmatch使用用于检查整个字符串是否与给定的模式完全匹配
re.fullmatch(pattern, string, flags0)pattern要匹配的正则表达式模式。
string要匹配的字符串。
flags可选用于控制正则表达式的匹配方式的标志。它要求模式与字符串完全一致即从字符串的开头到结尾都需要匹配。
import reword afd1456b23c32567def346# 不匹配afd开头后面是整个数字
result re.fullmatch(rafd\d, word)
print(result) # Noneword1 afd2333
result re.fullmatch(rafd\d, word1)
print(result) # re.Match object; span(0, 7), matchafd2333search、match、fullmatch匹配到的结果都是一个 re.Match 类型的对象。 finditer使用用于在字符串中查找所有匹配某个模式的子串并返回一个迭代器Iterator每个迭代项都是一个匹配对象。
re.finditer(pattern, string, flags0)pattern要匹配的正则表达式模式。
string要搜索的字符串。
flags可选用于控制正则表达式的匹配方式的标志。re.finditer()函数可以方便地获取所有匹配的子串适用于需要遍历并处理多个匹配结果的情况。
import reword afd1456b23c32567def346# 将字符串里所有匹配到的结果查询到得到的结果是一个迭代器
# 得到的迭代器里的每个元素又是一个 re.Match 类型的对象
result re.finditer(r3\d, word)
print(result) # re.Match object; span(11, 16), match32567for i in result:print(i)findall使用用于在字符串中查找所有匹配某个模式的子串并返回一个包含所有匹配结果的列表。
re.findall(pattern, string, flags0)pattern要匹配的正则表达式模式。
string要搜索的字符串。
flags可选用于控制正则表达式的匹配方式的标志。import reword afd1456b23c32567def346# 匹配到的结果字符串放在列表中返回
result re.findall(r3\d, word)
print(result) # [32567, 346]需要注意的是re.findall()函数只返回匹配结果的内容而不包含其他关于匹配位置等的信息。如果需要更详细的匹配信息可以使用re.finditer()函数。
4.re.Match对象与group
当使用re模块的函数进行匹配操作时如果匹配成功就会返回一个re.Match对象该对象包含关于匹配结果的信息。search、match、fullmatch、finditer匹配到的结果都有 re.Match 类型的对象。
查看re.Match对象的成员与方法
import reword afd1456b23c32567def346result re.search(r3\d, word)
print(dir(result))输出如下
[__class__, __copy__, __deepcopy__, __delattr__, __dir__, __doc__, __eq__, __format__, __ge__, __getattribute__, __getitem__, __gt__, __hash__, __init__, __init_subclass__, __le__, __lt__, __ne__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__, end, endpos, expand, group, groupdict, groups, lastgroup, lastindex, pos, re, regs, span, start, string]span()、string、group()
import reword afd1456b23c32567def346# 匹配到的结果字符串放在列表中返回
result re.search(r3\d, word)
print(result) # re.Match object; span(11, 16), match32567# print(dir(result))# 得到匹配到的字符串的开始和结束左闭右开
print(result.span(), word[result.span()[0]:result.span()[1]]) # (11, 16) 32567# 查找的完整的字符串
print(result.string) # afd1456b23c32567def346# 使用group获取匹配到的结果字符串
print(result.group()) # 32567re.Match对象的group()方法用于返回匹配的子串内容。
group()方法可以接受一个可选的参数group_num用于指定要返回的分组号。如果未提供group_num参数则默认返回整个匹配的子串。
import reword a10b2453c5896d717e123result re.search(rb\dc\dd\d, word)
print(result) # re.Match object; span(3, 17), matchb2453c5896d717
print(result.group()) # b2453c5896d717使用小括号进行分组 import reword a10b2453c5896d717e123# r(b\d)(c\d)(d\d) 有4个分组
# 第0组是整体其余3个括号是另外三个分组
result re.search(r(b\d)(c\d)(d\d), word)
print(result) # re.Match object; span(3, 17), matchb2453c5896d717
print(result.group()) # b2453c5896d717# 第0组是整体
print(result.group(0)) # b2453c5896d717
print(result.group(1)) # b2453
print(result.group(2)) # c5896
print(result.group(3)) # d717
groups()方法返回所有分组匹配的子串内容一个包含所有分组匹配结果的元组。
import reword a10b2453c5896d717e123print(result.groups()) # (b2453, c5896, d717)# groupdict以字典形式保存有组名的分组数据
# (?Pgroup_name) 用来设置组名
result re.search(r(?Pgroup_nameb\d)(c\d)(d\d), word)
print(result.groupdict()) # {group_name: b2453}groupdict()方法返回具名分组匹配的子串内容。
如果正则表达式模式中使用了具名分组即通过(?Pnamepattern)语法指定了分组的名称groupdict()方法将返回一个字典其中键是分组的名称值是匹配的子串内容。
import reword a10b2453c5896d717e123# groupdict以字典形式保存有组名的分组数据
# (?Pgroup_name) 用来设置组名
result re.search(r(?Pgroup_nameb\d)(c\d)(d\d), word)
print(result.groupdict()) # {group_name: b2453}5.re.compile
re.compile() 方法用于将正则表达式模式编译为一个可重复使用的正则表达式对象。
re.compile(pattern, flags0)pattern要编译的正则表达式模式。flags可选用于控制正则表达式的匹配方式的标志。
re.compile()方法的优点在于当需要多次使用同一个正则表达式模式时可以先编译为正则表达式对象然后重复使用该对象进行匹配避免了每次使用都要重新编译模式的性能开销。
import reword ab322wm234dasddpattern re.compile(rm\d)
print(pattern.search(word)) # re.Match object; span(6, 10), matchm2346.正则表达式修饰符
正则修饰符是对正则规则进行修饰让正则含有不同含义。使用修饰符也称为标志或选项来控制正则表达式的匹配方式。修饰符在re模块的函数中作为可选参数传递。
下面是常用的修饰符
re.I或re.IGNORECASE忽略大小写匹配。re.M或re.MULTILINE多行模式使^和$匹配每行的开头和结尾。re.S或re.DOTALL点.匹配包括换行符在内的所有字符。re.X或re.VERBOSE详细模式忽略空白和注释可以使用多行模式。
这些修饰符可以单独使用也可以使用位运算符|进行组合。
import reword ab322wm234Qasddprint(re.search(rq, word)) # None# re.I 忽略大小写
print(re.search(rq, word, re.IGNORECASE)) # re.Match object; span(10, 11), matchQ.表示除了\n以外的任意字符 import reword a\n1_*/({
# .表示除了\n以外的任意字符
print(re.findall(r., word)) # [a, 1, _, *, /, (, {, ]
# re.S匹配包括换行在内的所有字符
print(re.findall(r., word, re.S)) # [a, \n, 1, _, *, /, (, {, ]7.正则匹配规则 总的原则 1.数字和字母表示它本身没有特殊含义 2.\反斜杠有特殊含义用来做转义。大多数字母前面加\反斜杠以后会有不同含义。 3.标点符号只有被转义时才匹配自身否则它们表示特殊的含义。 4.反斜杠本身需要使用反斜杠转义。由于正则表达式通常都包含反斜杠所以最好使用原始字符串来表示它们。模式元素(如 r’\t’等价于\\t )匹配相应的特殊字符。 非打印字符也可以是正则表达式的组成部分。下表列出了表示非打印字符的转义序列
字符描述\cx匹配由x指明的控制字符。例如 \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则将 c 视为一个原义的 ‘c’ 字符。\f匹配一个换页符。等价于 \x0c 和 \cL。\n匹配一个换行符。等价于 \x0a 和 \cJ。\r匹配一个回车符。等价于 \x0d 和 \cM。\s匹配任何空白字符包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。\S(大写S)匹配任何非空白字符。等价于 [^\f\n\r\t\v]。\t匹配一个制表符。等价于 \x09 和 \cI。\v匹配一个垂直制表符。等价于 \x0b 和 \cK。 需要记住\r \n \t \s \S 特殊字符是一些有特殊含义的字符。若要匹配这些特殊字符必须首先使字符转义即将反斜杠字符\ 放在它们前面。下表列出了正则表达式中的特殊字符
特殊字符描述( )标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符请使用 \( 和 \)。.匹配除换行符 \n 之外的任何单字符。要匹配 . 请使用 \. 。[标记一个中括号表达式的开始。要匹配 [请使用 \[。\将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如 ‘n’ 匹配字符 ‘n’。‘\n’ 匹配换行符 \\ 匹配 \而 \( 则匹配 ( 。{标记限定符表达式的开始。要匹配 {请使用 \{。\d匹配一个数字字符。等价于 [0-9]。[0-9]匹配任何数字。等价于 \d\D匹配一个非数字字符。等价于 [^0-9]。[a-z]匹配任何小写字母[A-Z]匹配任何大写字母[a-zA-Z0-9]匹配任何字母及数字。等价于\w\w匹配包括下划线的任何单词字符。等价于[A-Za-z0-9_]。\W(大写W)匹配任何非单词字符。等价于 [^A-Za-z0-9_]。[\u4e00-\u9fa5]匹配纯中文 需要记住\d \D \w \W 定位符能够将正则表达式固定到行首或行尾。它们还能够创建这样的正则表达式这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。
定位符用来描述字符串或单词的边界^ 和 $ 分别指字符串的开始与结束\b 描述单词的前或后边界\B 表示非单词边界。
正则表达式的定位符有
特殊字符描述^匹配输入字符串的开始位置例如^h匹配以h开头在方括号表达式中时它表示不接受该字符集合例如[^0-9]匹配除了数字以外的数据。要匹配 ^ 字符本身请使用 \^。$匹配输入字符串的结尾位置。要匹配 $ 字符本身请使用 \$。\b匹配一个单词边界即字与空格间的位置。\B非单词边界匹配。 限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 ***** 或 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种。
正则表达式的限定符有
字符描述*匹配前面的子表达式零次或多次。例如zo* 能匹配 z 以及 zoo。 等价于{0,}。匹配前面的子表达式一次或多次。例如zo 能匹配 zo 以及 zoo但不能匹配 z。 等价于 {1,}。?匹配前面的子表达式零次或一次。例如do(es)? 可以匹配 do 、 does 中的 does 、 doxy 中的 do 。? 等价于 {0,1}。{n}n 是一个非负整数。匹配确定的 n 次。例如o{2} 不能匹配 Bob 中的 o但是能匹配 food 中的两个 o。{n,}n 是一个非负整数。至少匹配n 次。例如o{2,} 不能匹配 Bob 中的 o但能匹配 foooood 中的所有 o。o{1,} 等价于 o。o{0,} 则等价于 o*。{n,m}m 和 n 均为非负整数其中n m。最少匹配 n 次且最多匹配 m 次。请注意在逗号和两个数之间不能有空格。 示例
import rere.search(r\s, 大家好 我是 代码) # 匹配所有的空字符
re.search(r\S, 大家) # 匹配所有的非空字符
re.search(r\n, 大家好\n我是代码) # 匹配换行
re.search(rn$, hello python) # 匹配以 n 结尾
re.search(r^h.n$, hello python) # 匹配以 h 开头中间出现一次或多次任意字符并且以n结尾
re.search(r^ha*, h) # 匹配以 h 开头a出现0次或者一次8.正则表达式匹配练习 Q1用户名匹配:由数字、大小写字母、下划线_和中横线-组成长度为4到14位并且不能以数字开头。 import redef check_username(username):pattern r^[a-zA-Z_][a-zA-Z0-9_-]{3,13}$match re.match(pattern, username)if match:return Trueelse:return False# 测试用户名
usernames [user_123, User-Name, 123abc, _username, user-name, user_name_longer_than_14]
for username in usernames:if check_username(username):print(f{username}: 匹配)else:print(f{username}: 不匹配)
正则表达式模式解释
^匹配字符串的开头[a-zA-Z_]匹配一个字母、下划线或中横线不能以数字开头[a-zA-Z0-9_-]{3,13}匹配3到13个数字、大小写字母、下划线或中横线$匹配字符串的结尾 Q2匹配邮箱 import redef check_email(email):pattern r^[\w\.-][\w\.-]\.\w$match re.match(pattern, email)if match:return Trueelse:return False# 测试邮箱地址
emails [john.doeexample.com, jane_123gmail.com, invalid_email, userexample, admindomain]
for email in emails:if check_email(email):print(f{email}: 匹配)else:print(f{email}: 不匹配)
正则表达式模式解释
^匹配字符串的开头[\w\.-]匹配一个或多个字母、数字、下划线、点号或中横线邮箱用户名部分匹配邮箱地址中的[\w\.-]匹配一个或多个字母、数字、下划线、点号或中横线邮箱域名部分\.匹配邮箱地址中的点号\w匹配一个或多个字母、数字或下划线邮箱域名后缀$匹配字符串的结尾 Q3匹配手机号 import redef check_phone_number(phone_number):pattern r^1[3-9]\d{9}$match re.match(pattern, phone_number)if match:return Trueelse:return False# 测试手机号码
phone_numbers [13812345678, 15567891234, 12345678901, 189abcd1234, 01234567890]
for phone_number in phone_numbers:if check_phone_number(phone_number):print(f{phone_number}: 匹配)else:print(f{phone_number}: 不匹配)
正则表达式模式解释
^匹配字符串的开头1匹配手机号码的开头必须是1[3456789]匹配3、4、5、6、7、8、9中的一个数字\d{9}匹配9个数字手机号码的剩余部分$匹配字符串的结尾 Q4匹配身份证号。 import redef check_id_card(id_card):pattern r^[1-9]\d{16}(\d|X|x)$match re.match(pattern, id_card)if match:return Trueelse:return False# 测试身份证号码
id_cards [110101199003077934, 310110198706152518, 12345678901234567X, 123456789012345678, A1234567890123456]
for id_card in id_cards:if check_id_card(id_card):print(f{id_card}: 匹配)else:print(f{id_card}: 不匹配)
正则表达式模式解释
^匹配字符串的开头[1-9]匹配1到9中的一个数字身份证号码的开头不能为0\d{16}匹配16个数字身份证号码的剩余部分(\d|X|x)匹配一个数字或字母X身份证号码的最后一位校验位$匹配字符串的结尾 Q5匹配URL地址 import redef check_url(url):pattern r^(http|https)://[a-zA-Z0-9.-]\.[a-zA-Z]{2,}/?(\S)?$match re.match(pattern, url)if match:return Trueelse:return False# 测试URL地址
urls [http://www.example.com, https://www.example.com/path, ftp://www.example.com, www.example.com,http://example, https://123.456.789]
for url in urls:if check_url(url):print(f{url}: 匹配)else:print(f{url}: 不匹配)
正则表达式模式解释
^匹配字符串的开头(http|https)匹配http或https://匹配://[a-zA-Z0-9.-]匹配一个或多个字母、数字、点号或中横线域名部分\.[a-zA-Z]{2,}匹配一个点号后面跟着两个或更多字母域名后缀部分/?(\S)?匹配可选的斜杠后面跟着一个或多个非空字符路径部分$匹配字符串的结尾
9.正则替换
re.sub() 是 Python 中用于替换字符串中的匹配项的函数。它使用正则表达式来查找匹配项并使用提供的替换字符串来替换它们。re.sub() 函数的语法如下
re.sub(pattern, repl, string, count0, flags0)参数说明
pattern要匹配的正则表达式模式。repl用于替换匹配项的字符串或替换函数。string要进行替换的原始字符串。count可选参数指定替换的最大次数。默认为 0表示替换所有匹配项。flags可选参数用于控制正则表达式的匹配方式如 re.IGNORECASE忽略大小写匹配等。
re.sub() 函数的工作流程如下
在原始字符串 string 中查找与正则表达式模式 pattern 匹配的部分。对于每一个匹配项将其替换为 repl 字符串或替换函数的结果。返回替换后的字符串。 替换字符串中的匹配项
import retext Hello, World!
new_text re.sub(rHello, Hi, text)print(new_text) # Output: Hi, World!换字符串中的多个匹配项
import retext Hello, Hello, Hello!
new_text re.sub(rHello, Hi, text)print(new_text) # Output: Hi, Hi, Hi!使用替换函数
import redef to_uppercase(match):return match.group().upper()text hello, world!
new_text re.sub(r\b\w\b, to_uppercase, text)print(new_text) # Output: HELLO, WORLD!10.贪婪模式和非贪婪模式
贪婪模式和非贪婪模式是用于匹配字符串时的两种不同行为。它们涉及到量词quantifier的使用量词用于指定匹配模式中重复出现的次数。
贪婪模式Greedy Mode 贪婪模式是正则表达式的默认行为它会尽可能多地匹配字符串。当使用贪婪模式时量词会匹配尽可能多的字符。例如正则表达式 a.*b 匹配的是从第一个 a 到最后一个 b 之间的所有字符尽管可能有多个 a 和多个 b 存在。
非贪婪模式Non-Greedy Mode 非贪婪模式使用 ? 后缀来指示量词变为非贪婪模式。它会尽可能少地匹配字符串。当使用非贪婪模式时量词会匹配尽可能少的字符。例如正则表达式 a.*?b 匹配的是从第一个 a 到最近的 b 之间的字符只取最短的匹配结果。
下面通过示例来说明贪婪模式和非贪婪模式的区别
import repattern r.*
text a b cresult re.match(pattern, text)
print(result.group()) # a b c输出结果为a b c。在这个例子中正则表达式.*使用了贪婪模式它尝试匹配从第一个到最后一个之间的所有字符包括多个标签。
在Python正则表达式中可以使用?符号来表示非贪婪模式。
import repattern r.*?
text a b cresult re.match(pattern, text)
print(result.group()) # a这个正则表达式.*?使用了非贪婪模式?表示在*后面加上?表示非贪婪匹配。非贪婪模式尽量匹配最短的可能字符串所以它只匹配到了第一个之前的字符。