python正则表达式2
python正则表达式
一、正则修饰符
修饰符
|
描述
|
re.I
|
使匹配对大小写不敏感
|
re.M
|
多行匹配,影响^和$
|
re.S
|
使.匹配包括换行在内的所有字符
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #.表示除了换行以外的任意字符 import re m = re.search(r 'm.*a' , 'adfamo\nejoald' ) print (m) #None m1 = re.search(r 'm.*a' , 'adfamo\nejoald' ,re.S) print (m1) #<re.Match object; span=(4, 11), match='mo\nejoa'> m1 = re.search(r 'b' , 'aBc' ) print (m1) #None m2 = re.search(r 'b' , 'aBc' ,rs.I) print (m2) #<re.Match object; span=(1, 2), match='B'> #\w:表示的是字母数字和_ +:出现一次以上 $:以指定的内容结尾 m3 = re.findall(r '\w+$' , 'i am boy\n you are girl\n he is man' ) print (m3) #['man'] m4 = re.findall(r '\w+$' , 'i am boy\n you are girl\n he is man' ,re.M) print (m4) #['boy', 'girl', 'man'] |
二、正则表达式模式
1、字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。
1 | ret = re.search(r 'H' , 'Hello' ) #H表示字母H本身 |
2、多数字母和数字前加一个反斜杠时会拥有不同的含义。
1 | ret = re.search(r '\d' , 'ab34d2' ) #这里的\d表示匹配的是数字 |
3、标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。
1 2 | ret = re.search(r '.' , 'hello' ) #这里的.表示匹配任意一个字符 ret = re.search(r '\.' , 'hel.o' ) #这里的.进行了转义,表示标点符号自身 |
反斜杠本身需要使用反斜杠转义。由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 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
|
匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
|
\t
|
匹配一个制表符。等价于 \x09 和 \cI。
|
\v
|
匹配一个垂直制表符。等价于 \x0b 和 \cK。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import re # \s 表示任意的空白字符(空格、换行、制表符) print (re.search(r '\s' , 'hello world' )) # 空格 # <re.Match object; span=(5, 6), match=' '> print (re.search(r '\n' , 'hello\nworld' )) # 换行 # <re.Match object; span=(5, 6), match='\n'> print (re.search(r '\t' , 'hello world' )) # 制表符 # None # \S 表示非空白字符 print (re.search(r '\S' , '\t\n x' )) # <re.Match object; span=(4, 5), match='x'> |
- 特殊字符
特殊字符
|
描 述
|
$
|
匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,请使用 \$。
|
( )
|
标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。
|
*
|
匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
|
+
|
匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。
|
.
|
匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。
|
[
|
标记一个中括号表达式的开始。要匹配 [,请使用 \[。
|
?
|
匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。
|
\
|
将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\",而 '\(' 则匹配 "("。
|
^
|
匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 \^。
|
{
|
标记限定符表达式的开始。要匹配 {,请使用 \{。
|
|
|
指明两项之间的一个选择。要匹配 |,请使用 \|。
|
\d
|
匹配一个数字字符。等价于[0-9]。
|
[0-9]
|
匹配任何数字。等价于\d
|
\D
|
匹配一个非数字字符。等价于[^0-9]。
|
[a-z]
|
匹配任何小写字母
|
[A-Z]
|
匹配任何大写字母
|
[a-zA-Z0-9]
|
匹配任何字母及数字。
|
\w
|
匹配包括下划线的任何任何数字字母。等价于[a-zA-Z0-9_]。
|
\W
|
匹配任何非下划线数字字母。等价于[^a-zA-Z0-9_]。
|
[\u4e00-\u9fa5]
|
匹配纯中文。
|
- 定位符
定位符用来描述字符串或单词的边界,^ 和 $ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。
字符
|
描 述
|
^
|
匹配输入字符串的开始位置,例如:^h匹配以h开头;除非在方括号表达式中使用,此时它表示不接受该字符集合,例如[^0-9]匹配除了数字以外的数据。要匹配 ^ 字符本身,请使用 \^。
|
$
|
匹配输入字符串结尾的位置。如果设置了 Multiline 属性,$ 还会与 \n 或 \r 之前的位置匹配。要匹配 $ 字符本身,请使用 \$。
|
\b
|
匹配一个单词边界,即单词与空格间的位置。
|
\B
|
非单词边界匹配。
|
- 限定字符
正则表达式的限定符有:
字符
|
描述
|
*
|
匹配前面的子表达式零次或多次。例如,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 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。
|
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | import re #():用来表示一个分组 m = re.search(r 'h(\d+)x' , 'sh283xkfa' ) print (m.group(),m.group( 0 ),m.group( 1 )) #h283x h283x 283 m1 = re.search(r '\(.*\)' , '(1+1)*3+5' ) print (m1.group()) # (1+1) # . :用来匹配除了换行以外的任意字符。如果要匹配 . 需要使用 \. # [ ] :表示可选项范围 #[x,y] 从x到y区间,包括x和y m2 = re.search(r 'f[a-d]m' , 'pdsfcmsb' ) print (m2) #<re.Match object; span=(3, 6), match='fcm'> # | :用来表示或者 m3 = re.search(r 'f(x|pro|t)m' , 'adfpromw4' ) print (m3) #<re.Match object; span=(2, 7), match='fprom'> # {}:用来限定前面元素出现的次数 #{n}:表示前面的元素出现n次 #{n,}:表示前面的元素出现n次以上 #{,n}:表示前面的元素出现n次以下 #{n,m}:表示前面的元素出现m次到n次 print (re.search(r 'go{2}' , 'good' ).group()) #goo print (re.search(r 'go{2,}' , 'gooooood' ).group()) #goooooo # *:表示前面的元素出现任意次数,等价于{0,} print (re.search(r 'go*' , 'gooooooood' ).group()) #goooooooo # +:表示前面的元素至少出现一次,等价于{1,} #print(re.search(r'go+', 'gd').group()) #出错 #?:两种用法: #1.规定前面的元素最多出现一次,等价于{,1} #2.将贪婪模式转换成非贪婪模式 print (re.search(r 'go?d' , 'gd' ).group()) # gd # ^:字符串以指定的内容开头 $:指定内容结束 print (re.search(r '^a.*x$' , 'abcx' )) # abcx #^:在[]里还可以表示取反 print (re.search(r 'a[^0-9]+x' , 'faypxm5d' )) #aypx |
三、正则表达式练习
判断用户输入内容是否是数字,如果是数字转换为数字类型:
1 2 3 4 5 6 7 | import re num = input ( '请输入一段数字' ) if re.fullmatch(r '\d+\.?\d*' ,num): print ( '是个数字' ) print ( float (num)) else : print ( '不是一个数字' ) |
邮箱论证:
1 | ^([A - Za - z0 - 9_ \ - \.]) + @([A - Za - z0 - 9_ \ - \.]) + \.([A - Za - z]{ 2 , 4 })$ |
身份证论证:
1 | ^[ 1 - 9 ]\d{ 5 }( 18 | 19 | 20 )\d{ 2 }(( 0 [ 1 - 9 ])|( 10 | 11 | 12 ))(([ 0 - 2 ][ 1 - 9 ])| 10 | 20 | 30 | 31 )\d{ 3 }[ 0 - 9Xx ]$ |
四、正则替换
正则表达式作用是用来对字符串进行检索和替换
检索:match search fullmatch finditer findall
替换:sub
python中的re模块提供了re.sub用来替换字符串中的匹配项
语法:
1 | re.sub(pattern,repl,string,count = 0 ) |
由于字符串是不可变数据类型,因此用re.sub替换后生成新的字符串。
参数:
1 2 3 4 5 6 7 8 9 10 11 | import re phone = '138-0021-4576 #这是一个电话号码' # 删除注释 num = re.sub(r '#.*$' , '', phone) print (num) # 138-0021-4576 # 移除非数字 num1 = re.sub(r '\D' , '', phone) print (num1) # 13800214576 |
1 2 3 4 5 6 | def double(matched): test = int (matched.group( 'test' )) return str (test * 2 ) print (re.sub(r '(?P<test>\d+)' , double, 'hello23hi34' )) |
五、贪婪与非贪婪
1 2 3 4 5 | import re m = re.search(r 'm.*a' , 'e3fms6ajxxa9g' ) print (m.group()) #ms6ajxxa 贪婪模式 n = re.search(r 'm.*?a' , 'e3fms6ajxxa9g' ) print (n.group()) #ms6a 非贪婪模式 |
正则表达式模式中使用到通配符,那它从左向右的顺序求值时,会尽量“抓取”满足匹配最长字符串,在我们上边的例子中,“.*”会从字符串的开始处抓取满足模式的最长字符串,在字符串中抓取到后一个“a”之前的所有字符,即“ms6ajxxa”。而“.*?”会从开始处抓取满足模式的最短字符串,在字符串中抓取到第一个“a”后,结束匹配,即“ms6a ”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import re m1 = re.match(r 'aa(\d+)' , 'aa3345bbb' ) print (m1.group( 0 ),m1.group( 1 )) #aa3345 3345 m2 = re.match(r 'aa(\d+?)' , 'aa3345bbb' ) print (m2.group( 0 ),m2.group( 1 )) #aa3 3 m3 = re.match(r 'aa(\d+)bbb' , 'aa3345bbb' ) print (m3.group( 0 ),m3.group( 1 )) #aa3345bbb 3345 m4 = re.match(r 'aa(\d+?)bbb' , 'aa3345bbb' ) print (m4.group( 0 ),m4.group( 1 )) #aa3345bbb 3345 m5 = re.match(r 'aa(\d+?).*' , 'aa3345bbb' ) print (m5.group( 0 ),m5.group( 1 )) #aa3345bbb 3 m6 = re.match(r 'aa(\d??)(.*)' , 'aa3345bbb' ) print (m6.group( 0 ),m6.group( 1 ),m6.group( 2 )) #aa3345bbb 空 3345bbb |
示例:
字符串为:
1 | <imag data - original = 'https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg' src = 'https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg' style = 'display:inline;' > |
提取url地址:
1 | re.search(r 'https://.*?\.jpg' ,test) |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 《HelloGitHub》第 106 期
· 数据库服务器 SQL Server 版本升级公告
· 深入理解Mybatis分库分表执行原理
· 使用 Dify + LLM 构建精确任务处理应用