python成长之路第三篇(2)_正则表达式

时间:2023-03-08 17:52:56

打个广告欢迎加入linux,python资源分享群群号:478616847

目录:

1、什么是正则表达式,python中得正则简介

2、re模块的内容

3、小练习

一、什么是正则表达式(re)

正则表达式相信很多人都熟悉了,在python中正则表达式的支持是通过re(regular expression)模块,正则表达式是可以匹配文本片段的模式,简单的是正则表达式就是普通的字符串,可以处理字符串。也就是说正则表达式的存在就是来处理文本字符串的

下面来熟悉下正则中的几个概念:

1、通配符

通配符是一种特殊语句可以使用它来代替一个或多个真正的字符比如‘ . ’点,他就可以代替任意的字符除了换行符,.python就可以等于xpython、+python等等

2、字符集

既然通配符”.  ”可以表示一个任意的字符,那么字符集就可以表示一个字符的范围例如[a-z]就可以表示a-z的任意一个字符,还可以[a-zA-Z0-9]来表示大小写字母和数字,我们还可以将它来转义[^a]就是除了a的意思

注意的是这里的转意符不是单个\而是双\\

为什么使用两个反斜线?

这是为了通过解释器进行转义,需要进行两个级别的转义:1.通过解释器的转义;2.通过 re 模块转义。如果不想使用两个反斜线,可以考虑使用原始字符串,如:r'python\.org'。

3、选择符

为什么存在选择符呢?主要原因是假如我们想匹配两个字符串如“aaa”,“bbb”,我们就需要使用管道符(|)因此在匹配的时候就可以写成‘aaa|bbb’,当有的时候不需要匹配这两的时候假如只需要匹配字符串“aaa”或者“bbb”就可以写成“p(aaa|bbb)”

4、表示个数(重复模式)

表示个数顾名思义就是来表示这个字符有多少个的意思主要模式(pattern)有:

(pattern)*:表示这个模式可以重复0次或者多次

(pattern)+:表示允许这个模式出现一次或者多次

(pattern){m,n}:表示允许这个模式重复m到n次

(pattern){n}:表示重复n次

(pattern){n,} :表示重复n或者更多次,最低重复n次

5、表示开头和结尾

当我们要匹配以什么什么开头或者以什么什么结尾是表示开头我们可以使用‘^a’表示以a开头,’$a‘表示以a结尾

二、re模块的内容

既然我们知道re是个模块那么他肯定有很多功能函数来供我们使用下面我们来看一看

1 compile(pattern[, flags])                 根据包含正则表达式的字符串创建模式对象

2 search(pattern, string[, flags])        在字符串中寻找模式

3 match(pattern, string[, flags])         在字符串的开始处匹配模式

4 split(pattern, string[, maxsplit=0])   根据模式的匹配项来分割字符串

5 findall(pattern, string)                     列出字符串中模式的所有匹配项

6 sub(pat, repl, string[, count=0])      将字符串中所有pat的匹配项用repl替换

7 escape(string)                               将字符串中所有特殊正则表达式字符转义

这个compile我们最后来讲

首先我们来看看函数的语法:

 re.match(pattern, string, flags=0)

pattern:匹配的正则表达式

string:要匹配的字符串。

flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

匹配模式:

使用方法re.IGNORECASE,或者re.I

 I = IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE # ignore case
使匹配对大小写不敏感;字符类和字符串匹配字母时忽略大小写。举个例子,[A-Z]也可以匹配小写字母,Spam 可以匹配 "Spam", "spam", 或 "spAM"。这个小写字母并不考虑当前位置。 L = LOCALE = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale
影响 "w, "W, "b, 和 "B,这取决于当前的本地化设置。
locales 是 C 语言库中的一项功能,是用来为需要考虑不同语言的编程提供帮助的。举个例子,如果你正在处理法文文本,你想用 "w+ 来匹配文字,但 "w 只匹配字符类 [A-Za-z];它并不能匹配 "é" 或 "?"。如果你的系统配置适当且本地化设置为法语,那么内部的 C 函数将告诉程序 "é" 也应该被认为是一个字母。当在编译正则表达式时使用 LOCALE 标志会得到用这些 C 函数来处理 "w 後的编译对象;这会更慢,但也会象你希望的那样可以用 "w+ 来匹配法文文本。 U = UNICODE = sre_compile.SRE_FLAG_UNICODE # assume unicode locale
统一成unicode编码 M = MULTILINE = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline
使用 "^" 只匹配字符串的开始,而 $ 则只匹配字符串的结尾和直接在换行前(如果有的话)的字符串结尾。当本标志指定後, "^" 匹配字符串的开始和字符串中每行的开始。同样的, $ 元字符匹配字符串结尾和字符串中每行的结尾(直接在每个换行之前)。 S = DOTALL = sre_compile.SRE_FLAG_DOTALL # make dot match newline
使 "." 特殊字符完全匹配任何字符,包括换行;没有这个标志, "." 匹配除了换行外的任何字符。 X = VERBOSE = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments
该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。当该标志被指定时,在 RE 字符串中的空白符被忽略,除非该空白符在字符类中或在反斜杠之後;这可以让你更清晰地组织和缩进 RE。它也可以允许你将注释写入 RE,这些注释会被引擎忽略;注释用 "#"号 来标识,不过该符号不能在字符串或反斜杠之後。
 

re中的表示模式

模式

描述

^

匹配字符串的开头

$

匹配字符串的末尾。

.

匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。

[...]

用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'

[^...]

不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。

re*

匹配0个或多个的表达式。

re+

匹配1个或多个的表达式。

re?

匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式

re{ n}

 

re{ n,}

精确匹配n个前面表达式。

re{ n, m}

匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式

a| b

匹配a或b

(re)

G匹配括号内的表达式,也表示一个组

(?imx)

正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。

(?-imx)

正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。

(?: re)

类似 (...), 但是不表示一个组

(?imx: re)

在括号中使用i, m, 或 x 可选标志

(?-imx: re)

在括号中不使用i, m, 或 x 可选标志

(?#...)

注释.

(?= re)

前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。

(?! re)

前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功

(?> re)

匹配的独立模式,省去回溯。

\w

匹配字母数字

\W

匹配非字母数字

\s

匹配任意空白字符,等价于 [\t\n\r\f].

\S

匹配任意非空字符

\d

匹配任意数字,等价于 [0-9].

\D

匹配任意非数字

\A

匹配字符串开始

\Z

匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。c

\z

匹配字符串结束

\G

匹配最后匹配完成的位置。

\b

匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。

\B

匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。

\n, \t, 等.

匹配一个换行符。匹配一个制表符。等

\1...\9

匹配第n个分组的子表达式。

\10

匹配第n个分组的子表达式,如果它经匹配。否则指的是八进制字符码的表达式。

[Pp]ython

匹配 "Python" 或 "python"

rub[ye]

匹配 "ruby" 或 "rube"

[aeiou]

匹配中括号内的任意一个字母

[0-9]

匹配任何数字。类似于 [0123456789]

[a-z]

匹配任何小写字母

[A-Z]

匹配任何大写字母

[a-zA-Z0-9]

匹配任何字母及数字

[^aeiou]

除了aeiou字母以外的所有字符

[^0-9]

匹配除了数字外的字符

1、re .match(pattern, string, flags=0)

re.match从起始位置开始根据模型去字符串中匹配指定内容,匹配单个

  • 正则表达式
  • 要匹配的字符串
  • 标志位,用于控制正则表达式的匹配方式

我们来看一个例子

 import re
text = "111apple222pear"
f1 = re.match("\d+",text)
if f1:
print(f1.group())
else:
print("无")运行一下试试,我们可以发现匹配到了111,所以我们可以确定的是,match匹配的是从起始位置来去匹配,起始位置匹配到了则正常,否则返回空 “\d+”表示匹配任意数字出现1次或者更多次,如果把+号变成{1,2}你就发现匹配的结果是11,这是因为{1,2}表示匹配一个或两个

match

2、re.search(pattern, string, flags=0)

这个表示根据模式去匹配字符串中的匹配内容,也只匹配单个

 import re
text = "aaa111apple222pear"
f1 = re.search("\d+",text)
if f1:
print(f1.group())
else:
print("无")这个例子我们发现,re.search把111匹配出来了所以他就是从整个字符串中匹配出模式符合的字符串,并且只匹配第一个

searh

3、group()与groups()的区别

 import re
text = "jnj111apple222pear"
f1 = re.search("([0-9]+)([a-z]+)",text)
if f1:
print(f1.group(0),f1.group(1),f1.group(2)) print(f1.groups())
else:
print("无") 我们看上面的例子运行一下你就知道group和groups的区别了,看到结果清晰可见,re模块匹配到后会将值传入子组,group()默认不写参数就返回匹配的整个值,写入参数就返回参数对应的值,而groups()则返回匹配到的值的元组

group()and groups()

4、re.finadll(pattern, string, flags=0)

 上面两个例子我们不难看出都是匹配单个值的,那么finadll就是匹配所有符合条件的值

 import re
text = "jnj111apple222pear"
f1 = re.findall("([0-9]+)",text)
if f1:
print(f1)
else:
print("无")
执行上面的例子,得到的结果是个列表,列表中包含着所有符合条件的值([0-9]+)也可以写成(\d+)

finadll

5、re.sub(pattern, repl, string, count=0, flags=0)

 用于替换匹配条件的字符串

 import re
text = "jnj111apple222pear"
f1 = re.sub("([a-z]+)",'A',text)
if f1:
print(f1)
else:
print("无")输出的结果是所有的字母全变成大写的A了类似于str.repalce

sub

6、re.split(pattern, string, maxsplit=0, flags=0)

 import re
content = "a1*b2c3*d4e5"
new_content = re.split('[\*]', content,2)
print (new_content)
表示以*号作为分割符保持在列表中类似于str.split

split

7、compile(pattern, flags=0)

将匹配规则赋予对象,这样做的好处是可以提升匹配的速度

import re
content = "a1b*2c3*d4e5"
aaa = re.compile('[\*]')
new_content = re.split(aaa, content)
print (new_content)
还是上面的例子结果是一样的据官方解释说这种模式可以提升匹配的速率

8 、escape(string)  

将字符串中所有特殊正则表达式字符转义
import re
content = "a1b*2c3*d4e5"
ccc = re.escape(content)
print(ccc)

三、小练习

会了这些对于我们就足够了,对于复杂的匹配咱们可以百度一下滴,下面进行几个小练习

①匹配出其中的年龄字段

字符串是:"name: aaa , age:22 , user:1112"

 import re
str_in = 'name: aaa , age:22 , user:11121'
new_str_in = re.findall("[age]+\:\d{1,3}",str_in)
#表示age出现最低一次加上:号加上任意数字出现1到3次
print(new_str_in)

练习1

②匹配出字符串中的所有网址

字符串是:"The url is www.aaa.com wwa.ccc.dsa www.cdsa.c"
 import re
str_in = "The url is www.aaa.com wwa.ccc.dsa www.cdsa.c"
new_str_in = re.findall("www\.\S*\..{2,3}",str_in)#以www加.加任意非空字符加任意字符出现次数为2到3次
print(new_str_in)

练习2

③算出括号中的值并进行替换

字符串是:"The name is xiaoyan The money I have (5+5),6-1'
 import re
str_in = 'The name is xiaoyan The money I have (5+5),6-1'
new_str_in = re.findall("\(*\d+[\+]+\d+\)*",str_in)#匹配出括号中的内容
value = new_str_in[0].strip('(,)')#取出括号
n1, n2 = value.split('+')#以+作为分割付
new_value = str(int(n1)+int(n2))#进行计算
aaa = str_in.replace(new_str_in[0],new_value)#进行替换
print(aaa)

练习3