re库整理
Python语言专门提供了 re 模块,用于实现正则表达式的操作。在实现时,可以使用 re 模块提供的方法(如 search()、match()、findall()等)进行字符串处理,也可以先使用 re 模块的 compile() 方法将模式字符串转换为正则表达式对象,然后再使用该正则表达式对象的相关方法来操作字符串,接下来就跟大家介绍一下 re 模块的详细用法。
想要拿到re匹配的数据通过
.group()
方法可以返回匹配到的结果
一、使用re模块匹配字符串
re 模块中提供了 match()、search() 和 findall() 等方法专门用来匹配字符串,可以从海量数据中精确筛选出需要的对象,我们逐一来看看每种方法的具体实现。
1.使用match()方法进行匹配
match() 方法用于从字符串的开始处进行匹配,如果在起始位置匹配成功,则返回 Match 对象,否则返回 None。其语法格式如下:
re.match(pattern, string, [flags])
说明:match() 方法从字符串的开始位置开始匹配,一旦当第一个字母不符合条件时,则不再进行匹配,直接返回 None
参数说明:
- pattern:表示模式字符串,由要匹配的正则表达式转换而来。
- string:表示要匹配的字符串。
- flags:可选参数,表示标志位,用于
控制匹配方式,如是否区分字母大小写、是否包括换行
等等。常用的标志如下表所示。
标志 | 说明 |
---|---|
A 或 ASCII | 对于 \w、\W、\b、\B、\d、\D、\s 和 \S 只进行 ASCII 匹配(仅适用于Python3.x) |
I 或 IGNORECASE | 执行不区分字母大小写的匹配 |
M 或 MULTILINE | 将 ^ 和 $ 用于包括整个字符串的开始和结尾的每一行(默认情况下,仅适用于整个字符串的开始和结尾处) |
S 或 DOTALL | 使用(.)字符匹配所有字符,包括换行符 |
X 或 VERBOSE | 忽略模式字符串中未转义的空格和注释 |
Match 对象中包含了匹配值的位置和匹配数据。其中,要获取匹配值的起始位置可以使用 Match 对象的 start() 方法;要获取匹配值的结束位置可以使用 end() 方法;通过 span() 方法可以返回匹配位置的元组;通过 string 属性可以获取要匹配的字符串;通过 group() 方法可以返回匹配到的结果
。比如如下代码所示:
import re
string = 'MY_PHONE my_phone'
pattern = r'my_\w+'
match = re.match(pattern, string, re.I) # 匹配字符串,re.I设置为不区分大小写
print(match) # <re.Match object; span=(0, 8), match='MY_PHONE'>
print('匹配值的起始位置:', match.start())
print('匹配值的结束位置:', match.end())
print('匹配位置的元组:', match.span())
print('要匹配的字符串:', match.string)
print('匹配数据:', match.group())
"""
匹配值的起始位置: 0
匹配值的结束位置: 8
匹配位置的元组: (0, 8)
要匹配的字符串: MY_PHONE my_phone
匹配数据: MY_PHONE
"""
运行结果中匹配值的结束位置之所以是 8,是因为match() 方法匹配时,如果待匹配字符串中有多个符合规则的结果,也只返回第一个。 而匹配规则中 \w 是匹配字母、数字、下划线和汉字,所以匹配到中间空格那里第一个符合规则的结果就匹配结束了,即使后面有别的符合规则的结果,也不再进行匹配。
2.使用search()方法进行匹配
search() 方法用于在整个字符串中搜索第一个匹配的值,如果匹配成功,则返回 Match 对象,否则返回 None。search() 方法的语法格式如下:
re.search(pattern, string, [flags])
说明:search() 方法不仅是在字符串的起始位置搜索,其他位置上有符合的匹配也可以进行搜索,但是最终不论待匹配字符串中有多少个符合的结果,也只会返回一个。
参数说明:
- pattern:表示模式字符串,由要匹配的正则表达式转换而来。
- string:表示要匹配的字符串。
- flags:可选参数,表示标志位,用于
控制匹配方式,如是否区分字母大小写、是否包括换行
等等。常用的标志如下表所示。
import re
string = 'abcMY_PHONE my_phone'
pattern = r'my_\w+'
search = re.search(pattern, string, re.I) # 匹配字符串,re.I设置为不区分大小写
print(search) # <re.Match object; span=(3, 11), match='MY_PHONE'>
print('匹配值的起始位置:', search.start())
print('匹配值的结束位置:', search.end())
print('匹配位置的元组:', search.span())
print('要匹配的字符串:', search.string)
print('匹配数据:', search.group())
"""
匹配值的起始位置: 3
匹配值的结束位置: 11
匹配位置的元组: (3, 11)
要匹配的字符串: abcMY_PHONE my_phone
匹配数据: MY_PHONE
"""
3.使用findall()方法进行匹配
findall() 方法用于在整个字符串中搜索所有符合正则表达式的字符串,并以列表的形式返回所有符合条件的结果。如果匹配不成功,返回空列表。findall() 方法的语法格式如下:
re.findall(pattern, string, [flags])
说明:以上三种匹配方法,最常用的还是 findall() 方法,因为 match() 和 search() 均只能返回一个符合的结果,而findall()会将所有符合搜索条件的结果以列表的形式返回。
参数说明:
- pattern:表示模式字符串,由要匹配的正则表达式转换而来。
- string:表示要匹配的字符串。
- flags:可选参数,表示标志位,用于
控制匹配方式,如是否区分字母大小写、是否包括换行
等等。常用的标志如下表所示。
import re
string = 'abcMY_PHONE my_phone'
pattern = r'my_\w+'
findall = re.findall(pattern, string, re.I) # 匹配字符串,re.I设置为不区分大小写
print(findall) # ['MY_PHONE', 'my_phone']
二、使用 re 模块替换字符串
re 模块中的 sub() 方法用于实现字符串替换,语法格式如下:
re.sub(pattern, repl, string, count, flags)
参数说明:
- pattern:表示模式字符串,由要匹配的正则表达式转换而来。
- repl:表示要替换的字符串。
- string:表示要被查找替换的原始字符串。
- count:可选参数,表示模式匹配后替换的最大次数,默认值为 0,表示替换所有的匹配。
- flags:可选参数,表示标志位,用于控制匹配方式,如是否区分字母大小写、是否包括换行等等。
import re
string = '姓名 - 张三,学历 - 博士,性别 - 男'
result = re.sub(r' ', '-', string)
print(result) # 姓名---张三,学历---博士,性别---男
"""
第一个参数为模式字符串pattern表示需要被替换的是所有空格
第二个参数为替换字符串repl表示用-来替换所有该替换的空格
第三个参数为原始字符串 '姓名 - 张三,学历 - 博士,性别 - 男'
"""
三、使用re模块分割字符串
re模块中的split()方法用于实现根据正则表达式分割字符串,并以列表的形式返回。其作用如同字符串对象的split()方法类似,所不同的就是分割字符由模式字符串指定。split()方法的语法格式如下:
re.split(pattern, string, [maxsplit], [flags])
参数说明:
- pattern:表示模式字符串,由要匹配的正则表达式转换而来。
- string:表示要匹配的字符串。
- maxsplit:可选参数,表示最大的拆分次数。
- flags:可选参数,表示标志位,用于控制匹配方式,如是否区分字母大小写、是否包括换行等等。
import re
string = '姓名 - 张三,学历 - 博士,性别 - 男'
pattern = r' - |,'
result = re.split(pattern, string)
print(result) # ['姓名', '张三', '学历', '博士', '性别', '男']
"""
pattern = r' - |,' 表示分割规则是以"-"或者","来分割,只要满足其一就分割 |表示或
"""
四、其他
1.re.escape(pattern) 可以转义正则表达式中具有特殊含义的字符,比如:.
或者 *
import re
text = '你好.真好*啊'
pattern = re.escape('你好.真好*啊')
print('转义后的正则:', pattern) # 转义后的正则: 你好\.真好\*啊
print('search:', re.search(pattern, text))
# search: <re.Match object; span=(0, 7), match='你好.真好*啊'>
五、正则表达式细讲
在处理字符串时,经常会有查找符合某些复杂规则的字符串的需求。比如用爬虫批量抓取某网站图片,要从抓下来的网页信息中提取出所有的图片地址,这时候正则表达
式就派上了用场,正则表达式就是记录文本规则的代码
,有了它,我们可以从海量数据里面精准筛选出需要的那部分内容。今天就详细来看看正则表达式中的特殊字符以及详细用法。
一、行定位符
行定位符就是用来描述字符串的边界,“^
” 表示行的开始,“$
” 表示行的结尾。比如:
^Ha
该表达式表示要匹配字符串的开头位置是 Ha,如 “Hangzhou is a very beautiful city” 可以匹配,而 “Your words are very funny, Ha” 则不匹配。但如果使用:
Ha$
后者可以匹配而前者不能匹配。如果要匹配的字符串可以出现在字符串的任意部分,那么可以写成下面的格式,这样两个字符串都能匹配上。
Ha
二、元字符
除了前面介绍的"^
"和"$
"外,正则表达式里还有更多的元字符,例如下面的正则表达式中就应用了元字符"\b
"和"\w
"。
\ban\w*\b
上面的正则表达式用于匹配以字母 an 开头的字符串,先从字符串的开头 an 处开始匹配,接着是任意数量的字母或数字(\w*)。该表达式可以匹配 “anaconda” 和 “and246”,但不能与 “abandon” 匹配。更多常见元字符如下表所示:
元字符 | 说明 | 举例 |
---|---|---|
. | 匹配除换行符以外 的任意字符 |
. 可以匹配 “acd\n8R\t” 中的 a、c、d、8、R、\t |
\w | 匹配字母、数字、下划线或汉字 | \w 可以匹配 “miO次9\nqw” 中的 “m、i、O、次、9、q、w”,但不能匹配 \n |
\W | 匹配除字母、数字、下划线或汉字以外的字符 | \W 可以匹配 “92d\nsc” 中的 \n,但不能匹配 “9、2、d、s、c” |
\s | 匹配单个的空白符(包括 Tab 键和换行符) | \s 可以匹配 “c\t8B” 中的 \t |
\S | 匹配除单个空白符(包括 Tab 键和换行符)以外的所有字符 | \S 可以匹配 “字we2\t90” 中的 “字、w、e、2、9、0” |
\b | 匹配单词的开始或结束,单词的分解符通常是空格,标点符号或者换行 | 在 “there were deserts where” 字符串中,\bw 与 were 中的 w 相匹配,但与 where 中的 w 不匹配 |
\d | 匹配数字 | \d 可以与 “dg34&” 中的 3、4 匹配 |
三、限定符
在上面例子中,使用(\w*)可以匹配任意数量的字母或数字。但如果想要匹配指定数量的数字该如何表示呢?
正则表达式为我们提供了限定符(指定数量的字符) 来实现该功能。如匹配 11 位电话号码可使用如下表达式:
^\d{11}$
常用的限定符如下表所示:
限定符 | 说明 | 举例 |
---|---|---|
? | 匹配前面 的字符 0 次或 1 次 |
Pyth?on,该表达式可以匹配 Python 和 Pyton |
+ | 匹配前面 的字符 1 次或多次 |
Py+thon,该表达式可以匹配的范围从 Python 到 Pyy…thon |
* | 匹配前面 的字符 0 次或多次 |
Pyt*hon,该表达式可以匹配的范围从 Pyhon 到 Pytt…hon |
匹配前面 的字符 n 次 |
Pytho{3}n,该表达式只匹配 Pythooon | |
匹配前面 的字符至少 n 次 |
Pytho{3,}n,该表达式可以匹配的范围从 Pythooon 到 Pythooo…n | |
匹配前面 的字符最少 n 次,最多 m 次 |
P{1,3}ython,该表达式可以匹配 Python、PPython、PPPython |
四、字符类
正则表达式查找数字和字母是很简单的,因为已经有了对应这些字符集合的元字符(如 “\d”、“\w”),但是如果要匹配没有预定义元字符的字符集合(比如只匹配元音字母a,e,i,o,u),应该怎么办?
很简单,只需要在方括号里列出它们就行了,像 [aeiou] 可以匹配任何一个英文元音字母,[.?!] 匹配标点符号(“.”,“?”,“!”),也可以轻松的指定一个范围,像 “[0-9]” 代表的含义与 “\d” 就是完全一致的:代表一位数字。同理,“[a-z0-9A-Z_]” 完全等同于 “\w”(如果只考虑英文的话)。
五、排除字符
在上面的字符类中列出的匹配符合指定字符集合的字符串。现在反过来,匹配不符合指定字符集合的字符串。正则表达式提供了 “^
” 字符。这个元字符在上面出现过,表示行的开始。而这里将会放到方括号中,表示排除的意思。例如:
[^a-zA-Z]
六、选择字符
试想一下,如何匹配身份证号码?首先需要了解一下身份证号码的规则。身份证号码长度为 18 位,前 17 位为数字,最后一位是校验位,可能为数字或字符 X。
在上面的描述中,包含着条件选择的逻辑,这就需要使用选择字符(|)来实现。该字符可以理解为 “或”,匹配身份证的表达式可以写成如下方式:
(^\d{18}$)|(^\d{17})(\d|X|x)$
该表达式的意思是匹配 18 位数字,或者 17 位数字和最后一位。最后一位可以是数字,也可以是 X 或者 x。
七、转义字符
正则表达式中的转义字符(\)和 Python 中的大同小异,可以将字符本身的含义转成特定的含义,如果是特殊字符(比如 “.” “?” “\” 等)则转变为普通的字符。举一个 IP 地址的实例,用正则表达式匹配诸如 “127.0.0.1” 格式的 IP 地址。如果直接使用点字符,格式为:
[1-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}
这显然不对,因为 “.” 可以匹配一个任意字符。这时,不仅是127.0.0.1 这样的 IP,连 127a0b0c1 这样的字符串也会被匹配出来。所以在使用 “.” 时,需要使用转义字符(\)。修改后上面的正则表达式格式为:
[1-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
说明:括号在正则表达式中也算是一个元字符。
八、分组
通过上面的选择字符板块,大家对小括号的作用有了一定了解。小括号字符的第一个作用就是可以改变限定符的作用范围,如 “|” “*” “^” 等。例如下面的表达式中包含小括号。
(fruit|food)s
这个表达式的意思是匹配单词 fruits 或 foods,如果不使用小括号,那么就变成了匹配单词 fruit 和 foods 了。
小括号的第二个作用是分组,也就是子表达式。如 ([a-z]{1,3}){3},就是对分组 ([a-z]{1,3}) 进行重复操作。
九、正则表达式语法
在Python中使用正则表达式时,是将其作为模式字符串使用的。例如,将匹配不是字母的一个字符的正则表达式表示为模式字符串,可以使用下面的代码:
'[^a-zA-Z]'
而如果将匹配以字母 g 开头的单词的正则表达式转换为模式字符串,则不能直接在其两侧添加引号定界符,例如,下面的代码是不正确的。
'\bg\w*\b'
而是需要将其中的 “\” 进行转义,转换后的结果为:
'\\bg\\w*\\b'
由于模式字符串中可能包括大量的特殊字符和反斜杠,所以需要写为原生字符串
,即在模式字符串前加 r 或 R
。例如,上面的模式字符串采用原生字符串表示为:
r'\bg\w*\b'
说明:在编写模式字符串时,并不是所有的反斜杠都需要进行转换,没有特殊意义的就不用转。
标签:字符,匹配,re,正则表达式,pattern,Re,正则,字符串,整理 From: https://www.cnblogs.com/piggthird/p/18381872