python-re模块(正则表达式)

正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符"),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本。

        本篇文章更多的是记录一些知识点。是在知道正则表达式,会使用re模块的前提下进行编写。

目录

功能标志

元字符

修饰符

字符集[]

高级语法(非贪婪、先行后行断言、命名组及条件匹配)

非标记组(?:expr)

贪婪/非贪婪模式

正向先行断言(?=expr)

负向先行断言(?!expr)

命名组

re模块

compile函数

1、compile()与findall()一起使用,返回一个列表。

2、compile()与match()一起使用,可返回一个class、str、tuple,dict。

3、compile()与search()搭配使用

4、隐藏的 compile 函数

re中的正则匹配函数

1、match()函数(以后常用)

2、search()函数

3、findall()函数

4、split()函数

5、 sub()函数

6、subn()函数

Scanner类


功能标志

标志缩写说明
ASCIIA仅执行8位的ASCII码字符匹配
IGNORECASEI匹配不区分大小写
DEBUG输出调试信息
MULTILINEM多行模式,使用热数字夫^和$匹配行首和行尾以及字符串的开头和结尾
DOTALL使用点运算符(.)匹配所有字符,包括行尾符(\n) 
UNICODEU使用UNICODE格式匹配字母数字字符、单词边界和数字
VERBOSEV冗长模式,可以在正则表达式中添加注释,忽略空白字符等。

以IGNORECASE为例介绍使用方法:

# 正则表达式,匹配任意个小写字母
regx = "[a-z]*"

# 开头是大写字母的单词
s1 = "Vencent"

# 使用IGNORECASE标志后,忽略了字母大小写,匹配成功
re.match(regx, s1, re.IGNORECASE)[0]    # <re.Match object; span=(0, 7), match='Vencent'>

# 不使用IGNORECASE标志,匹配失败
re.match(regx, s1)[0]    # <re.Match object; span=(0, 0), match=''>

元字符

特殊字符说明
.点运算符,匹配除换行符以外的任何一个字符。如果启用DOTALL标志,将匹配任何字符
^插入符号,匹配字符串的开始。如果启用MULTILINE标志,则它也匹配换行符后的任意字符。(在字符集里[^a]表示非,不匹配)
$匹配字符串的结尾,如果启用MULTILINE标志,则它也匹配换行符或末尾的最后一个字符
\A匹配字符串的开头

\b

匹配单词的边界,如r“De\b"匹配"De asfa",但不匹配"Deasfa"
\B匹配非单词边界,与\b相反的含义
\d匹配任何数字字符(0-9)。如果设置了UNICODE标志,还包括归类为数字的Unicode字符。
\D匹配任何非数字的字符
\s匹配任何空白字符,可以是空格或这几个转义字符(\t、\n、\r、\f、\v)。
\S匹配\s中定义的空白字符意外的任何字符
\w匹配任何字母、数字或下划线。
\W匹配\w中定义的字符外的任何字符
\z匹配字符串的结尾

示例:

# 正则表达式,匹配全部是数字的字符串
regx = r"^\d*$"

d1 = "12345"
d2= "123s765"

# d1匹配成功
re.match(regx, d1)    # <re.Match object; span=(0, 5), match='12345'>

# d2匹配失败
re.match(regx, d2)    # None

修饰符

修饰符说明
*重复零次或更多次
+重复1次或多次
重复0次或1次
|或匹配
{n}重复n次
{m,n}重复m-n次
{m,}至少重复m次,没有上限
{,n}重复0-n次
()将()中的表达式视为一个组(子表达式)。如(asd)+可以匹配"asd"、"asdasdasd"
\数字指前面已经匹配到的内容(实际找到的内容,而非表达式)。\1表示第一组找到的文本,\2表示第二组...

示例:

# |的方法
re.match(r"abc|edf", "edf")    # <re.Match object; span=(0, 3), match='edf'>

# {m,n}的用法
re.match(r"\d{1,5}", "12345678")    # <re.Match object; span=(0, 5), match='12345'>

# ()的用法
re.match(r"(asd)+", "asdasdasd")    # <re.Match object; span=(0, 9), match='asdasdasd'>

# \数字的用法,下面示例是指遇到第一个重复的数字就停止,用到了非贪婪模式,后面介绍
re.match(r"(\d).*?\1", "123412341234")    # <re.Match object; span=(0, 5), match='12341'>

字符集[]

[char_set]  表示匹配字符集中的任意一个字符

# 正则表达式,两个s之间可以是abcd中的任意字符
regx = r"s[abcd]s"

s1 = "sas"
s2 = "scs"
s3 = "ses"

re.match(regx, s1)    # <re.Match object; span=(0, 3), match='sas'>

re.match(regx, s2)    # <re.Match object; span=(0, 3), match='scs'>

re.match(regx, s3)    # None

[^char_set] 表示匹配不在字符集中的任意一个字符(^在开头时)

# 正则表达式,两个s之间不能是abcd中的任意字符
regx = r"s[^abcd]s"

s1 = "sas"
s2 = "scs"
s3 = "ses"

re.match(regx, s1)    # None

re.match(regx, s2)    # None

re.match(regx, s3)    # <re.Match object; span=(0, 3), match='ses'>

字符在 [] 中,并且只能出现一次,并且特殊字符写在 [] 会被当成普通字符来匹配。

# []中的特殊字符被当作普通字符识别
re.match(r".*[*+^$-]", "dsgg352t*35931y5")    # <re.Match object; span=(0, 9), match='dsgg352t*'>

负号-如果出现在两个字符之间,则表示两个字符范围内的字符,否则负号-视为普通字符(如上一条示例)。[a-zA-Z0-9]表示任何大小写字母或数组。

regx = r"[a-zA-Z0-9]"

re.match(regx, "1")    # <re.Match object; span=(0, 1), match='1'>
re.match(regx, "F")    # <re.Match object; span=(0, 1), match='F'>
re.match(regx, "g")    # <re.Match object; span=(0, 1), match='g'>

匹配多个字符或表达式的时候,可以用()

# 匹配Tom或Lily或Vencent或\d{3}
regx = r"(Tom|Lily|Vencent|\d{3})"

re.match(regx, "Tom is boy")    # <re.Match object; span=(0, 3), match='Tom'>

re.match(regx, "Lily is girl")    # <re.Match object; span=(0, 4), match='Lily'>

re.match(regx, "Vencent is toy")    # <re.Match object; span=(0, 7), match='Vencent'>

re.match(regx, "123455678")    # <re.Match object; span=(0, 3), match='123'>

高级语法(非贪婪、先行后行断言、命名组及条件匹配)

语法(expr是表达式)说明
(?:expr)

非标记组。将expr视为一个单元,但不在运行时标记匹配到的字符。该表达式只用于字符匹配,而不会记录匹配到的字符。相应的(expr)表示标记组

expr???运算符的非贪婪模式
expr*?*运算符的非贪婪模式
expr+?+运算符的非贪婪模式
expr{m,n}?{m,n}运算符的非贪婪模式
(?=expr)正向先行断言。如果expr与当前位置之后的字符串匹配,则表达式整体匹配成功;否则,表达式匹配失败。与言行断言匹配的字符不会被消除或标记,它们被视为尚未读取,这意味这下一个正则表达式操作可以再次读取它们
(?!expr)负向先行断言。如果expr与当前位置之后的字符串不匹配,则表达式整体匹配成功;这些字符既不会被消除,也不被标记,因此它们仍将被下一个正则表达式匹配或搜索操作读取
(?<=expr)

正向后行断言。如果当前位置之前的字符可以匹配expr,则表达式整体匹配成功。这里的expri必须为固定长度。该模式的意思是,重新读取已经处理过的字符,且以这种方式重新读取的字符不会被标记。

例如,给定表达式(?<=abd)def,字符串abcdef中的def可以被匹配,但是abc并不是匹配对象的一部分。该模式的意思是,仅当abc在def之前时匹配def

(?<!expr)负向后行断言。如果当前位置之前的字符不能匹配expr,则表达式整体匹配成功。这里的expr必须为固定长度。该模式的意思是,重新读取已经处理过的字符,且以这种方式被重新读取的字符不会被标记
(?P<name>expr)命名组。如果expr匹配,则整体表达式匹配成功。匹配成功的字符串会被标记,并被赋予一个名称,在其他表达式中可以使用名称引用它们
(?P=name)匹配命名组。如果字符串与之前匹配成功的命名组相同,则此表达式匹配成功。
(#text)注释。该字段可以出现在正则表达式中,但是会被正则表达式程序忽略

(?(name)yespat|nopat)

(?(name)yespat)

(?(id)yespat|nopat)

(?(id)yespat)

条件匹配。如果命名组先前已经出现并成功匹配,则此表达式将尝试匹配yespat;否则,它将尝试匹配nopat。id是标记组的序号

下面是每种语法的示例

  • 非标记组(?:expr)

# 非标记组(?:expr)
regx1 = r"\d{1,3}(?:,\d{3})*(?:\.\d*)?\b"

s1 = "12,000 monkeys on 100 typewriters for 53.12 days"

lst1 = re.findall(regx1, s1)

for item in lst1:
    print(item)

'''
12,000
100
53.12
'''

##########################################################################

# 标记组(expr)
regx2 = r"\d{1,3}(,\d{3})*(\.\d*)?\b"

s1 = "12,000 monkeys on 100 typewriters for 53.12 days"

lst2 = re.findall(regx2, s1)

for item in lst2:
    print(item)

'''
(',000', '')
('', '')
('', '.12')
'''

贪婪/非贪婪模式

# 贪婪模式
regx1 = r"<.*>"

s1 = "<h1>This is an HTML heading.</h1>"

re.match(regx1, s1)    # <re.Match object; span=(0, 33), match='<h1>This is an HTML heading.</h1>'>


# 非贪婪模式
regx2 = r"<.*?>"

re.match(regx2, s1)    # <re.Match object; span=(0, 4), match='<h1>'>

正向先行断言(?=expr)

# 正向先行断言(?=expr)
regx = r"[A-Z].*?[.!?](?= [A-Z]|$)"

s1 = '''I am M.X.B. Today is a nice day. But I need study. I
will go out after 1 hour!'''

lt = re.findall(regx, s1, re.DOTALL|re.MULTILINE)

for item in lt:
    print("->", item)

'''
-> I am M.X.B.
-> Today is a nice day.
-> But I need study.
-> I
will go out after 1 hour!
'''

# 这里是用于判断英文句子的正则表达式
# [A-X]表示开头大写字母
# .*?表示匹配任意数量字符(非贪婪模式)
# [.!?]表示.或!或?,用于标志句子结尾
# (?= [A-Z]|$)是先行断言判断条件,如果不满足则表示并不是完整句子
# re.DOTALL表示.可以表示换行符
# re.MULTILINE表示$可以表示换行符和结尾符号

负向先行断言(?!expr)

# 负向先行断言(?!expr)
regx = r"\d(?!-)"

s1 = "1-2-3-4-5-6sa21r5"

re.findall(regx, s1)    # ['6', '2', '1', '5']

# 这里是匹配数字且数字后面不跟负号-
# \d表示匹配一个数字
# (?!-)表示\d匹配到的数字后面不能跟负号-

(?<=expr)和(?=expr)功能类似,只是往前匹配。

(?<!expr)和(?!expr)也是功能类似,只是往前匹配。

命名组

#(?P<name>expr) 使用名称标记匹配的组
#(?P=name) 尝试再次匹配该命名组
regx = "Name=(?P<name>[a-zA-Z]*)(?=\W).*?Age=(?P<age>\d*)(?=\W).*City=(?P<city>[a-zA-Z]*)(?=\W).*(?P=name) is (?P<gender>man|woman|boy|gril)"

s1 = '''Name=Max
Age=34
City=NanJing
Lily is woman
Lucy is gril
Tom is boy
Max is man'''

lt = re.match(regx, s1, re.DOTALL)

matchs = re.match(regx, s1, re.DOTALL)

print(matchs.group("name"))   # Max
print(matchs.group("age"))    # 34
print(matchs.group("city"))   # NanJing
print(matchs.group("gender")) # man

print(matchs.group(1))        # Max
print(matchs.group(2))        # 34
print(matchs.group(3))        # NanJing
print(matchs.group(4))        # man

# (?P<name>[a-zA-Z]*)(?=\W) 获取名字
# (?P<age>\d*)(?=\W) 获取年龄
# (?P<city>[a-zA-Z]*)(?=\W) 获取城市
# (?P=name) 匹配姓名,以区分多个姓名
# (?P<gender>man|woman|boy|gril) 获取性别

re模块

compile函数

compile 函数用于编译正则表达式,生成一个 Pattern 对象,它的一般使用形式如下:

re.compile(pattern,flag=0)
'''
pattern: 正则模型
falgs : 匹配模式,比如忽略大小写,多行模式等
返回值: Pattern 对象
'''

import re
# 将正则表达式编译成 Pattern 对象 
pattern = re.compile(r'\d+')

1、compile()与findall()一起使用,返回一个列表。

import re
def main():
    content = 'Hello, I am Jerry, from Chongqing, a montain city, nice to meet you……'
    regex = re.compile('\w*o\w*')
    x = regex.findall(content)
    print(x)
if __name__ == '__main__':
    main()
# ['Hello', 'from', 'Chongqing', 'montain', 'to', 'you']

2、compile()与match()一起使用,可返回一个class、str、tuple,dict。

compile()与match()一起使用,可返回一个class、str、tuple,dict。 但是一定需要注意match(),从位置0开始匹配,匹配不到会返回None,返回None的时候就没有span/group属性了,并且与group使用,返回一个单词‘Hello’后匹配就会结束。

import re
def main():
    content = 'Hello, I am Jerry, from Chongqing, a montain city, nice to meet you……'
    regex = re.compile('\w*o\w*')
    y = regex.match(content)
    print(y)
    print(type(y))
    print(y.group())
    print(y.span())
    print(y.groupdict())
 
if __name__ == '__main__':
    main()
# <_sre.SRE_Match object; span=(0, 5), match='Hello'>
# <class '_sre.SRE_Match'>
# Hello
# (0, 5)
# {}

3、compile()与search()搭配使用

compile()与search()搭配使用, 返回的类型与match()差不多, 但是不同的是search(), 可以不从位置0开始匹配。但是匹配一个单词之后,匹配和match()一样,匹配就会结束。

import re
def main():
    content = 'Hello, I am Jerry, from Chongqing, a montain city, nice to meet you……'
    regex = re.compile('\w*o\w*')
    z = regex.search(content)
    print(z)
    print(type(z))
    print(z.group())
    print(z.span())
    print(z.groupdict())
if __name__ == '__main__':
    main()
# <_sre.SRE_Match object; span=(0, 5), match='Hello'>
# <class '_sre.SRE_Match'>
# Hello
# (0, 5)
# {}

4、隐藏的 compile 函数

正常情况下 我们使用re模块时,我们都是先调用re模块的complie函数生成成pattern对象,使用pattern对象调用相应的方法进行正则匹配。一般代码写成下面的样子。

import re
pattern = re.compile('正则表达式')
text = '一段字符串'
result = pattern.findall(text)

但是在Python里面,在大多数情况下真的不需要使用re.compile!,直接使用re.对应的方法(pattern, string, flags=0)就可以了其原因就是热模块将complie函数的调用放在了对应的方法(pattern, string, flags=0)中了。我们常用的正则表达式方法,无论是findall还是search还是sub还是match,其返回值全部都是这样写的:

_compile(pattern, flag).对应的方法(string)

查看源码:

def findall(pattern, string, flags=0):
    """Return a list of all non-overlapping matches in the string.
    If one or more capturing groups are present in the pattern, return
    a list of groups; this will be a list of tuples if the pattern
    has more than one group.
    Empty matches are included in the result."""
    return _compile(pattern, flags).findall(string)

果然是这个样子。实际上我们常用的正则表达式方法,都已经自带了compile了!
一般情况下不需要先使用re.compile再调用正则表达式方法。
再看一下re.compile源码

def compile(pattern, flags=0):
    "Compile a regular expression pattern, returning a Pattern object."
    return _compile(pattern, flags)

也是调用 _compile(pattern, flags)返回pattern对象。

如果我有一百万条字符串,使用某一个正则表达式去匹配,那么我可以这样写代码:

texts = [包含一百万个字符串的列表]
pattern = re.compile('正则表达式')
for text in texts:
    pattern.search(text)

这个时候,re.compile只执行了1次,而如果你像下面这样写代码:

texts = [包含一百万个字符串的列表]
for text in texts:
    re.search('正则表达式', text)

相当于你在底层对同一个正则表达式执行了100万次re.compile。是不是这样子呢?答案是:不是,

红框中的代码,说明了 _compile自带缓存。它会自动储存最多512条由type(pattern), pattern, flags)组成的Key,只要是同一个正则表达式,同一个flag,那么调用两次_compile时,第二次会直接读取缓存。
综上所述,再大多数情况下不需要手动调用re.compile,除非你的项目涉及到几百万以上的正则表达式查询。

re中的正则匹配函数

1、match()函数(以后常用)

match,从开头匹配一个符合规则的字符串,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None。如果匹配的字符不是在开头处,那么它将会报错,匹配成功返回结果,没有返回None。

match(pattern, string, flags=0)
# pattern: 正则模型
# string : 要匹配的字符串
# falgs : 匹配模式

import  re
str="hello egon bcd egon lge egon acd 19"
r=re.match("h\w+",str) #match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None,非字母,汉字,数字及下划线分割
print(r.group()) # 获取匹配到的所有结果,不管有没有分组将匹配到的全部拿出来
print(r.groups()) # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果
print(r.groupdict())  # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分定义了key的组结果
# hello
# ()
# {}
 
 
r2=re.match("h(\w+)",str) #match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None
print(r2.group())
print(r2.groups())
print(r2.groupdict())
 
# hello
# ('ello',)
# {}
 
r3=re.match("(?P<n1>h)(?P<n2>\w+)",str)  #?P<>定义组里匹配内容的key(键),<>里面写key名称,值就是匹配到的内容
print(r3.group())
print(r3.groups())
print(r3.groupdict())
 
# hello
# ('h', 'ello')
# {'n1': 'h', 'n2': 'ello'}

2、search()函数

search:浏览全部字符串,匹配第一符合规则的字符串,浏览整个字符串去匹配第一个,未匹配成功返回None

search(pattern, string, flags=0)
# pattern: 正则模型
# string : 要匹配的字符串
# flags : 匹配模式

注意:match()函数 与 search()函数基本是一样的功能,不一样的就是match()匹配字符串开始位置的一个符合规则的字符串,search()是在字符串全局匹配第一个合规则的字符串

import  re
str="hello egon bcd egon lge egon acd 19"
r=re.search("h\w+",str) #match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None,非字母,汉字,数字及下划线分割
print(r.group()) # 获取匹配到的所有结果,不管有没有分组将匹配到的全部拿出来
print(r.groups()) # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果
print(r.groupdict())  # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分定义了key的组结果
 
# hello
# ()
# {}
 
 
r2=re.search("h(\w+)",str) #match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None
print(r2.group())
print(r2.groups())
print(r2.groupdict())
 
# hello
# ('ello',)
# {}
 
r3=re.search("(?P<n1>h)(?P<n2>\w+)",str)  #?P<>定义组里匹配内容的key(键),<>里面写key名称,值就是匹配到的内容
print(r3.group())
print(r3.groups())
print(r3.groupdict())
 
# hello
# ('h', 'ello')
# {'n1': 'h', 'n2': 'ello'}

3、findall()函数

浏览全部字符串,匹配所有合规则的字符串,匹配到的字符串放到一个列表中,未匹配成功返回空列表

findall(pattern, string, flags=0)
# pattern: 正则模型
# string : 要匹配的字符串
# flags : 匹配模式

注意: 一旦匹配成,再次匹配,是从前一次匹配成功的,后面一位开始的,也可以理解为匹配成功的字符串,不在参与下次匹配

'''
注意: 一旦匹配成,再次匹配,是从前一次匹配成功的,后面一位开始的,也可以理解为匹配成功的字符串,不在参与下次匹配
'''
import re
r=re.findall("\d+\w\d+","a2b3c4d5") #浏览全部字符串,匹配所有合规则的字符串,匹配到的字符串方到一个列表中
print(r)
# ['2b3', '4d5'] #匹配成功的字符串,不再参与下次匹配,所以3c4也符合规则但是没有匹配到

注意:正则匹配到空字符的情况,如果规则里只有一个组,而组后面是就表示组里的内容可以是0个或者多过,这样组里就有了两个意思,一个意思是匹配组里的内容,二个意思是匹配组里0内容(即是空白)所以尽量避免用否则会有可能匹配出空字符串
注意:正则只拿组里最后一位,如果规则里只有一个组,匹配到的字符串里在拿组内容是,拿的是匹配到的内容最后一位

'''
注意:正则匹配到空字符的情况,如果规则里只有一个组,而组后面是*就表示组里的内容可以是0个或者多过,这样组里就有了两个意思,一个意思是匹配组里的内容,二个意思是匹配组里0内容(即是空白)所以尽量避免用*否则会有可能匹配出空字符串
注意:正则只拿组里最后一位,如果规则里只有一个组,匹配到的字符串里在拿组内容是,拿的是匹配到的内容最后一位
'''
import re
r=re.findall("(ca)*","ca2b3caa4d5") #浏览全部字符串,匹配所有合规则的字符串,匹配到的字符串方到一个列表中
print(r)
# ['ca', '', '', '', 'ca', '', '', '', '', '']#用*号会匹配出空字符

无分组:匹配所有合规则的字符串,匹配到的字符串放到一个列表中

'''
注意:正则匹配到空字符的情况,如果规则里只有一个组,而组后面是*就表示组里的内容可以是0个或者多过,这样组里就有了两个意思,一个意思是匹配组里的内容,二个意思是匹配组里0内容(即是空白)所以尽量避免用*否则会有可能匹配出空字符串
注意:正则只拿组里最后一位,如果规则里只有一个组,匹配到的字符串里在拿组内容是,拿的是匹配到的内容最后一位
'''
import re
r=re.findall("(ca)*","ca2b3caa4d5") #浏览全部字符串,匹配所有合规则的字符串,匹配到的字符串方到一个列表中
print(r)
# ['ca', '', '', '', 'ca', '', '', '', '', '']#用*号会匹配出空字符

无分组:匹配所有合规则的字符串,匹配到的字符串放到一个列表中

'''
无分组:匹配所有合规则的字符串,匹配到的字符串放到一个列表中
'''
import re
r=re.findall("a\w+","ca2b3 caa4d5") #浏览全部字符串,匹配所有合规则的字符串,匹配到的字符串方到一个列表中
print(r)
# ['a2b3', 'aa4d5']#匹配所有合规则的字符串,匹配到的字符串放入列表

多个分组:只将匹配到的字符串里,组的部分放到一个元组中,最后将所有元组放到一个列表里返
相当于在group()结果里再将组的部分,分别,拿出来放入一个元组,最后将所有元组放入一个列表返回

'''
多个分组:只将匹配到的字符串里,组的部分放到一个元组中,最后将所有元组放到一个列表里返
相当于在group()结果里再将组的部分,分别,拿出来放入一个元组,最后将所有元组放入一个列表返回
'''
import re
r=re.findall("(a)(\w+)","ca2b3 caa4d5") #有多分组:只将匹配到的字符串里,组的部分放到一个元组中,最后将所有元组放到一个列表里返回
print(r)
# [('a', '2b3'), ('a', 'a4d5')]#返回的是多维数组

分组中有分组:只将匹配到的字符串里,组的部分放到一个元组中,先将包含有组的组,看作一个整体也就是一个组,把这个整体组放入一个元组里,然后在把组里的组放入一个元组,最后将所有组放入一个列表返回

'''
分组中有分组:只将匹配到的字符串里,组的部分放到一个元组中,先将包含有组的组,看作一个整体也就是一个组,把这个整体组放入一个元组里,然后在把组里的组放入一个元组,最后将所有组放入一个列表返回
'''
import re
r=re.findall("(a)(\w+(b))","ca2b3 caa4b5") #分组中有分组:只将匹配到的字符串里,组的部分放到一个元组中,先将包含有组的组,看作一个整体也就是一个组,把这个整体组放入一个元组里,然后在把组里的组放入一个元组,最后将所有组放入一个列表返回
print(r)
# [('a', '2b', 'b'), ('a', 'a4b', 'b')]#返回的是多维数组

?:在有分组的情况下findall()函数,不只拿分组里的字符串,拿所有匹配到的字符串,注意?:只用于不是返回正则对象的函数如findall()

'''
?:在有分组的情况下findall()函数,不只拿分组里的字符串,拿所有匹配到的字符串,注意?:只用于不是返回正则对象的函数如findall()
'''
import re
r=re.findall("a(?:\w+)","a2b3 a4b5 edd") #?:在有分组的情况下,不只拿分组里的字符串,拿所有匹配到的字符串,注意?:只用于不是返回正则对象的函数如findall()
print(r)
# ['a2b3', 'a4b5']

4、split()函数

根据正则匹配分割字符串,返回分割后的一个列表

split(pattern, string, maxsplit=0, flags=0)
# pattern: 正则模型
# string : 要匹配的字符串
# maxsplit:指定分割个数
# flags  : 匹配模式


import  re
r=re.split("a\w","sdfadfdfadsfsfafsff")
print(r)
r2=re.split("a\w","sdfadfdfadsfsfafsff",maxsplit=2)
print(r2)
 
# ['sdf', 'fdf', 'sfsf', 'sff']
# ['sdf', 'fdf', 'sfsfafsff']

5、 sub()函数

替换匹配成功的指定位置字符串

sub(pattern, repl, string, count=0, flags=0)
# pattern: 正则模型
# repl   : 要替换的字符串
# string : 要匹配的字符串
# count  : 指定匹配个数
# flags  : 匹配模式


import  re
r=re.sub("a\w","替换","sdfadfdfadsfsfafsff")
print(r)
 
# sdf替换fdf替换sfsf替换sff

6、subn()函数

替换匹配成功的指定位置字符串,并且返回替换次数,可以用两个变量分别接受

subn(pattern, repl, string, count=0, flags=0)
# pattern: 正则模型
# repl   : 要替换的字符串
# string : 要匹配的字符串
# count  : 指定匹配个数
# flags  : 匹配模式


import  re
a,b=re.subn("a\w","替换","sdfadfdfadsfsfafsff") #替换匹配成功的指定位置字符串,并且返回替换次数,可以用两个变量分别接受
print(a) #返回替换后的字符串
print(b) #返回替换次数
 
# sdf替换fdf替换sfsf替换sff
# 3

Scanner类

re模块提供了Scanner用于高效地匹配多个正则表达式,并对匹配的字符串进行处理。这里记录下使用方法和示例。

'''
# 定义扫描器和处理函数(处理函数可以单独定义也可以使用lambda)
scanner_name =  re.Scanner([
    (tok_pattern1, funct1),
    (tok_pattern2, funct2),
    ...
    )]

# 调用scan函数进行扫描
scanner_name.scan(string)
'''

# 定义处理函数,<scanner>是对扫描器对象的引用,<tok_str>是对匹配到的字符串的引用
def sc_int(scanner, tok_str):
    return int(tok_str)

# 定义扫描器,这里分别用了定义函数和lambda
scanner = re.Scanner([
    (r"\d+\.\d*", lambda scanner, tok_str: float(tok_str)),
    (r"\d+",      sc_int),
    (r"\s+",      None)
    ])

# 调用scan函数进行扫描
scanner.scan("1 532 5.125 1245 sdgs 123 2wq")    # ([1, 532, 5.125, 1245], 'sdgs 123 2wq')

# 返回值是有2个元素的元组
# 一个是包含所有搜索结果的列表
# 另一个是包含未成功匹配的文本字符串

参考资料

python中的re模块_顺其自然~的博客-CSDN博客

《高阶Pyhon代码精进之路》

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,您想了解Python正则表达式re模块。re模块Python的标准库之一,用于处理正则表达式正则表达式是一种用于匹配和搜索文本的模式,它可以用来检查字符串是否符合特定的格式,或者从字符串中提取想要的信息。 re模块提供了一系列函数和方法来操作正则表达式,包括: - re.compile(pattern, flags):编译正则表达式,返回一个正则表达式对象。 - re.search(pattern, string, flags):在字符串中搜索匹配正则表达式的第一个位置,返回一个匹配对象。 - re.match(pattern, string, flags):从字符串开头开始匹配正则表达式,返回一个匹配对象。 - re.findall(pattern, string, flags):返回字符串中所有匹配正则表达式的子串列表。 - re.sub(pattern, repl, string, count=0, flags=0):用指定的替换字符串替换字符串中所有匹配正则表达式的子串,返回替换后的字符串。 其中,pattern参数是正则表达式,string参数是要匹配的字符串,flags参数是可选的标志,用来控制正则表达式的行为。 例如,下面的代码展示了如何使用re模块来匹配一个简单的正则表达式: ```python import re text = 'Hello, World!' pattern = r'Hello' match = re.search(pattern, text) if match: print('Match found:', match.group()) else: print('No match') ``` 输出结果为: ``` Match found: Hello ``` 以上就是Python正则表达式re模块的基本介绍,希望能帮到您。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值