首页 > 编程语言 >PYTHON - 正则表达式

PYTHON - 正则表达式

时间:2023-03-24 11:04:39浏览次数:54  
标签:匹配 string re PYTHON 正则表达式 result print regexp

1.1 正则

正则表达式(Regular Expression),在代码中是预先定义好的一个规则串,这个规则串可以匹配,查找,替换那些符合规则的文本。

1.2 正则表达式字符串

正则表达式的字符串由普通字符和元字符组成。

  • 普通字符

按字面的意义表示的字符,如 abcd 等,表示字符本身的意义。

  • 元字符

用于描述其它字符的特殊字符,它由基本元字符和普通字符组成。元字符是预先定义好的一些特定字符,如:\w+

1.3 元字符

基本元字符:

字符 说明
\ 转义符
. 表示任意一个字符
+ 表示重复一次或多次
* 表示重复零次或多次
? 表示重复零次或一次
| 选择符号,表示或关系
{} 定义量词,表示重复指定次数
[] 定义字符集(字符范围)
() 定义分组
^ 表示字符集中的取反,或匹配一行的开始
$ 表示匹配一行的结束

1.4 转义

对于元字符,如果想要表示字符本身的意义,比如. 就表示点,而不是表示任意字符,则需要转义:

\.

元字符前面加一个斜杠,就表示元字符字符本意。

1.5 开始与结束

^ 表示一行的开始, $ 表示一行的结束

import re

email = 'myccloves@163.com'
regexp = r'^\w+@.*com$'
result = re.match(regexp, email)
print(result)  # 匹配

\w 表示[a-zA-z0-9_]

这个正则表示以字母,或数字,或下划线组成字符串开头(重复),后跟一个@,后跟任意字符,以com结尾

1.6 字符集

[] 把需要匹配的字符放到方括号里,比如:[Aa] 表示匹配A或者a

import re

email = 'myccloves@163.com'
regexp = r'[coes]ve'
result = re.search(regexp, email)
print(result)  # 匹配: cve, ove, eve, sve 这里匹配到了ove

1.6.1 字符集取反

表示不在字符集中的字符

[^字符] 比如:[^a] 表示除了a,其它的字符都匹配。

import re

email = 'myccloves@163.com'
regexp = r'[^0123456789]+'
result = re.search(regexp, email)
print(result) # 匹配到了myccloves@

1.6.2 字符集区间

表达了一个范围:[开始-结束], 比如:[a-z] 匹配字符a到字符z之间所有的字符。

import re

email = 'myccloves@163.com'
regexp = r'[a-z]+'
result = re.search(regexp, email)
print(result) # 匹配myccloves

1.7 预定义字符

预先定义好的一些正则字符

字符 说明
\n 换行
\r 回车
\f 换页
\t 水平制表
\v 垂直制表
\s 空白符,相当于 [\t\n\r\f\v]
\S 非空白符,相当于 [^\s]
\d 数字,相当于[0-9]
\D 非数字,相当于[^0-9]
\w 匹配字母,数字,下划线。字母不限于英文
\W 等价于[^\w]
\b 单词边界
\B 等价于 [^\b]

1.8 量词

用于表示字符或字符串重复的次数。

字符 说明
? 出现零次或一次
* 出现零次或多次
+ 出现一次或多次
{n} 出现n次
{n,m} 出现n次,但不超过m次,m>次数>=n
{n,} 至少出现n次
import re

string = '87654321'
regexp = r'\d{3,4}'
result = re.search(regexp, string)
print(result)  # 匹配8765

1.8.1 贪婪和懒惰

默认是贪婪的,尽可能多的匹配,而懒惰最少匹配。懒惰匹配在量词后面加一个问号。

import re

string = '87654321'
regexp = r'\d{3,5}?'
result = re.search(regexp, string)
print(result) # 匹配876,按最少的匹配。

如:

import re

string = '<h1>hello</h1><h2>welcome!</h2>'
regexp = r'<h.>.*</h.>'
result = re.search(regexp, string)
print(result) # 匹配所有,贪婪的

regexp = r'<h.>.*?</h.>'
result = re.search(regexp, string)
print(result) # 只匹配<h1>hello</h1>, 尽可能少的匹配

1.9 分组

之前的量词只能重复一个字符,如果想让一个字符串作为整体使用量词,可以用分组。

分组也称为子表达式。

import re

string = 'abcabc1234151234'
regexp = r'(abc){2}'  # 表示abc重复2次:abcabc
result = re.search(regexp, string)
print(result)

import re

string = '0437-6337700'
regexp = r'(\d{4})-(\d{7})' # 有两个组
result = re.search(regexp, string)

print(result)  # 匹配成功, 输出Match对象
print(result.group())  # 0437-6337700
print(result.group(1))  # 0437
print(result.group(2))  # 6337700
print(result.groups()) # ('0437', '6337700')

group(1) 表示取出第一个组匹配的数据,group(2)表示取出第二个组匹配的数据

groups() 返回所有组中的内容,返回一个元组。

1.9.1 分组的命名

(?P<组名> ...) 分组命名之后,可以通过组名来返回匹配内容。

import re

string = '0437-6337700'
regexp = r'(?P<area>\d{4})-(?P<tel>\d{7})' # 有两个组
result = re.search(regexp, string)

print(result.group('area'))  # 0437
print(result.group('tel'))  # 6337700

1.9.2 反向引用分组

下例中的:\1 表示引用第一个分组,依此类推。

import re

string = '<h1>aaaa</h1>'
regexp = r'<(\w+)>.*</\1>+'  # \w是啥,后面的\1就是啥。比如:h1后面的\1就是h1
result = re.search(regexp, string)

print(result)

1.9.3 非捕获分组

有时候不需要捕获某个分组的内容,但又想使用分组的特性,可以使用非捕获组。

string = '1.txt,2.txt,3.txt,4.txt'
regexp = r'\d(\.txt)'
result = re.findall(regexp, string)

# 得到的都是分组中的内容
print(result)  # ['.txt', '.txt', '.txt', '.txt']

# 需要将小()中的内容作为一个整体匹配,前面加?:变成非捕获分组
result = re.findall(r'\d(?:\.txt)', string)
print(result) # ['1.txt', '2.txt', '3.txt', '4.txt']

2.1 re模块

re模块内置正则表达式模块。

2.1.1 search和match函数

search(pattern, string, flags=0)
match(pattern, string, flags=0)

这两个函数都用来进行第一次匹配,如果匹配返回Match对象,不匹配返回None

区别:

  • search 在字符串中查找匹配
  • match 在字符串开头进行匹配
import re

s = "abc12345abc54321"
m = re.search(r'\d+', s)
print(type(m))  # re.Match对象
print(m.group())  # 匹配的数据
print(m.start())  # 3 匹配的开始位置
print(m.end())  # 8 匹配的结束位置
print(m.span()) # 匹配的开始和结束位置,以元组返回

对于match对象,如果开头不匹配直接返回None

import re

s = "abc12345abc54321"
m = re.match(r'\d+', s)
print(m) # None

2.1.2 findall和finditer函数

findall(pattern, string, flags=0)
finditer(pattern, string, flags=0)

这两个函数返回所有匹配(search,match只返回第一次匹配), 匹配失败返回空列表

区别:

  • findall 如果匹配成功返回匹配的数据
  • finditer 如果匹配成功返回可迭代对象,遍历每个Match元素对象,得到匹配数据
import re

s = "abc12345abc54321"
m = re.findall(r'\d+', s)
print(m)  # ['12345', '54321']

it = re.finditer(r'\d+',s)
for m in it:
    print(type(m))
    print(m.group())

2.1.3 split函数

用于字符串分割,返回列表。

split(pattern, string, maxsplit=0, flags=0)

maxsplit表示最多分割几次

import re

s = "abc12345abc54321sdfsdfs33sadfs22"
result = re.split(r'\d+', s, maxsplit=1)
print(result)  # ['abc', 'abc54321sdfsdfs33sadfs22']
import re

s = "abc12345abc54321sdfsdfs33sadfs22"
result = re.split(r'\d+', s)
print(result) # ['abc', 'abc', 'sdfsdfs', 'sadfs', '']

2.1.4 sub函数

用于字符串替换

sub(pattern, repl, string, count=0, flags=0)

count表示替换几次

import re

s = "abc12345abc54321sdfsdfs33sadfs22"
result = re.sub(r'\d+', ',', s, count=3)
print(result) # abc,abc,sdfsdfs,sadfs22

3.1 编译正则表达式

编译的正则可以重复使用,减少正则表达式的解析和验证,提高效率。

re.compile(pattern, flags=0)

这个函数返回一个Pattern对象,Pattern对象中调用相应的方法实现匹配,替换,分割等。

方法
search(self, /, string, pos=0, endpos=9223372036854775807)
match(self, /, string, pos=0, endpos=9223372036854775807)
findall(self, /, string, pos=0, endpos=9223372036854775807)
finditer(self, /, string, pos=0, endpos=9223372036854775807)
sub(self, /, repl, string, count=0)
split(self, /, string, maxsplit=0)

这些功能同re模块中的函数类似,前四个pos表示开始位置,endpos表示结束位置,从这个范围内进行匹配。

import re

s = "abc12345abc54321sdfsdfs33sadfs22"
p = re.compile(r'\d+')
result = p.match(s, pos=3)
print(result.group())  # 12345

3.1.2 编译标志

标志 说明
re.I, re.IGNORECASE 不区分大小写
re.L, re.LOCALE 根据所使用的本地语言环境通过\w,\W,\b,\B,\s,\S实现匹配
re.M, re.MULTILINE 多行模式,对于^和$产生影响。
re.S, re.DOTALL . (点号)一般匹配除了\n的所有字符,标记后点号匹配所有
re.X, re.VERBOSE 详细模式,可以添加注释,允许有空格,换行
import re

s = """1234
5678
abc
90"""
print(re.findall(r'^\d+', s))  # ['1234']
print(re.findall(r'^\d+', s, re.MULTILINE))  # ['1234', '5678', '90']

如果有多个标志可以用|串联。

import re

s = "abc123\nAbc456\nABc789"

result = re.findall(r'^abc\d+', s, re.IGNORECASE | re.MULTILINE)
print(result) # ['abc123', 'Abc456', 'ABc789']

标签:匹配,string,re,PYTHON,正则表达式,result,print,regexp
From: https://www.cnblogs.com/three-sheep/p/17250739.html

相关文章