首页 > 其他分享 >正则表达式详解

正则表达式详解

时间:2024-07-10 10:55:13浏览次数:13  
标签:字符 匹配 正则表达式 pattern re 详解 字符串

1. 正则表达式的作用

(1)文本搜索和匹配:可以用来搜索、匹配和替换特定模式的文本。

          比如,查找所有符合特定格式的邮箱地址、电话号码等。

(2)数据验证:可以用来验证用户输入是否符合特定的格式要求。

          比如,验证电子邮件地址、密码复杂度等。

(3)数据提取:可以从复杂的文本中提取出需要的信息。

          比如,从网页源码中抽取出所有链接地址。

(4)文本处理:可以用来进行文本的分割、替换、删除等操作。

          比如,删除所有的空格或者特定标记。

(5)语法分析和编译:在编译器和解释器中,正则表达式可以用来识别和处理语法结构。

          比如,编程语言中的词法分析阶段,识别关键字、变量名等。

(6)字符串操作:可以用来处理和操作字符串,进行复杂的模式匹配和处理。

          比如,对文本进行格式化、规范化等操作。

总之,正则表达式在处理需要模式匹配和字符串操作的场景中非常有用,能够提高处理字符串的效率和灵活性。

2.  正则表达式语法

正则表达式(Regular Expression)的语法主要分为普通字符、元字符。

2.1 普通字符

在正则表达式中,普通字符指的是除了元字符和转义字符以外的任意字符,包括字母、数字、标点符号、空格等。

普通字符在正则表达式中的匹配方式是按照字符的字面意义(表示其本身意义)进行匹配。

以下是一些常见的正则表达式中的普通字符及其含义:

  • 字母和数字:代表匹配该字母或数字本身。

  • 空格和标点符号:代表匹配该空格或标点符号本身。

  • 下划线(_):代表匹配下划线本身。下划线(_):代表匹配下划线本身。

2.2 元字符

元字符是正则表达式中的特殊字符,用来表示特定的字符或字符组合,用来表示特殊的匹配含义。

包括:

代码功能
.(英文点号)匹配任意1个字符(除了\n换行符)。 例如,正则表达式 a.b 可以匹配 aabacba4b,但是不匹配 a\nb
^(脱字符)匹配以某个字符串开头。 例如,正则表达式 ^hello 可以匹配 hello world 中的 hello,但是不匹配 world hello 中的 hello
$(美元符号)匹配以某个字符串结尾。 例如,正则表达式 world$ 可以匹配 hello world 中的 world,但是不匹配 world hello 中的 world
*(星号)匹配前一个字符出现0次或者无限次,即可有可无(0到多,任意次)。 例如,正则表达式 ab*c 可以匹配 acabcabbc,但是不匹配 aabcc
+(加号)匹配前一个字符出现1次或者无限次,即至少有1次(1到多,一次以上)。 例如,正则表达式 ab+c 可以匹配 abcabbc,但是不匹配 aca
?(问号)匹配前一个字符出现1次或者0次,即要么有1次,要么没有(0或1)。 例如,正则表达式 ab?c 可以匹配 acabc,但是不匹配 abbc
|(竖杠)选择匹配符,表示或,匹配两边任意一个表达式,可以匹配多个规则。 例如,正则表达式 hello\|world 可以匹配 helloworld
()(英文小括号)用于分组,或叫子表达式,可以更精确地控制匹配。 例如,正则表达式 (ab)+ 可以匹配 ababab,只有由 "ab" 组成的字符串才能匹配 (ab)+,且可以重复匹配多个 "ab" 形成的字符串。
[](方括号)用于指定字符集,匹配方括号中出现的任意一个字符。 例如,正则表达式 [abc] 可以匹配 abc,但是不匹配 dab
[^指定字符]匹配除了指定字符以外的其他某个字符,^在字符集里表示取反。
{m}匹配前一个字符出现m次。例如,匹配手机号码\d{11}
{m,}匹配前一个字符至少出现m次。例如,\w{3,}代表前面这个字符最少要出现3次,最多可以是无限次。
{m,n}匹配前一个字符出现从m到n次。例如,\w{6,10}代表前面这个字符出现6到10次。
\用于转义,表示后面的字符不是特殊字符。

2.3 常用字符集

基于元字符,有一些常用的字符集。

字符集是由一组字符组成的集合,用方括号 [] 表示,用于匹配方括号中出现的任意一个字符。

例如:

代码功能
[abc]表示匹配a、b、c中的任意一个字符。
[a-z]表示匹配a到z之间的任意一个小写字母。
[A-Z]表示匹配A到Z之间的任意一个大写字母。
[0-9]表示匹配0到9之间的任意一个数字。
[^abc]表示匹配除了a、b、c之外的任意一个字符,^在字符集里表示取反。
[0-9a-zA-Z]表示匹配0-9之间、a-z之间、A-Z之间的任意某个字符。

在字符集中,还可以使用特殊字符来表示一些常用字符集。

例如:

代码功能
\d匹配数字,即[0-9]
\D匹配非数字,即不是数字,[^0-9]
\s匹配空白,即 空格,tab键(制表符),换行符。
\S匹配非空白。
\w匹配非特殊字符,匹配任意一个字母、数字或下划线,相当于[a-zA-Z0-9_]
\W匹配特殊字符,匹配任意一个非字母、数字或下划线,相当于[^a-zA-Z0-9_]

3. re模块

re 模块是 Python 中用于正则表达式操作的标准库,提供了一组用于处理字符串匹配、查找、替换等操作的函数和方法。

在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用re模块。

3.1 re模块使用

# 第一步:导入re模块
import re
# 第二步:使用match方法进行匹配操作
result = re.match(pattern正则表达式, string要匹配的字符串, flags=0)
# 第三步:如果数据匹配成功,使用group方法来提取数据
result.group()

match函数参数说明:

参数描述
pattern匹配的正则表达式
string要匹配的字符串。
flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志

说明:

  • 匹配成功re.match方法返回一个匹配的对象,否则返回None。

  • 我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配数据。

正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

修饰符描述
re.I使匹配对大小写不敏感
re.L做本地化识别(locale-aware)匹配,这个功能是为了支持多语言版本的字符集使用环境的,比如在转义符\w,在英文环境下,它代表[a-zA-Z0-9 _],即所以英文字符和数字。如果在一个法语环境下使用,缺省设置下,不能匹配"é" 或 "ç"。加上这L选项和就可以匹配了。不过这个对于中文环境似乎没有什么用,它仍然不能匹配中文字符。
re.M多行匹配,影响 ^ 和 $
re.S使 . 匹配包括换行在内的所有字符
re.U根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.XVERBOSE,冗余模式, 此模式忽略正则表达式中的空白和#号的注释,例如写一个匹配邮箱的正则表达式。该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。

3.2 re模块的相关方法

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

用于从字符串的开头匹配正则表达式。

如果匹配成功,则返回一个匹配对象;否则返回 None。

可选参数 flags 用于控制正则表达式的匹配方式,后面的几个方法中的flags参数都是一样的作用,常用的有如下几种:

  • re.I 或 re.IGNORECASE:I代表Ignore,忽略大小写。

  • re.M 或 re.MULTILINE:多行匹配,改变^$的行为。

  • re.S 或 re.DOTALL:让"."匹配包括换行符在内的所有字符。

  • re.X 或 re.VERBOSE:忽略空格和注释,让正则表达式更易读。

示例:

import re
​
# 匹配以数字开头的字符串
result = re.match(r'\d+', '123abc')
​
if result:
    print(result.group())  # 输出: 123
else:
    print('No match')

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

用于在字符串中查找第一个匹配正则表达式的位置。

如果匹配成功,则返回一个匹配对象;否则返回 None。

示例:

import re
​
# 查找第一个匹配的数字
result = re.search(r'\d+', 'I have 2 apples and 3 oranges')
​
if result:
    print(result.group())  # 输出: 2
else:
    print('No match')

(3)re.findall(pattern, string, flags=0)

用于在字符串中查找所有匹配正则表达式的位置,并返回一个匹配结果的列表。

示例:

import re
​
# 查找所有匹配的数字
result = re.findall(r'\d+', 'I have 2 apples and 3 oranges')
​
print(result)  # 输出: ['2', '3']

(4)re.finditer(pattern, string, flags=0)

是 re 模块中的函数,用于搜索字符串中与正则表达式匹配的所有子串,并返回一个迭代器。

功能与上面findall一样,不过返回的是迭代器。

函数语法:

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

参数说明:

  • pattern:正则表达式模式。

  • string:要被搜索的字符串。

  • flags:正则表达式使用时的标志位。

返回值:返回一个迭代器,包含所有匹配的子串。

用法示例:

import re
​
string = "Hello 123 World 456"
pattern = r'\d+'
​
for match in re.finditer(pattern, string):
    print(match.group())

输出结果:


说明:

  • 正则表达式 r'\d+' 用于匹配字符串中的数字字符。

  • re.finditer() 函数返回一个迭代器,包含所有匹配的子串,我们可以使用 for 循环遍历迭代器,并通过 match.group() 方法获取匹配到的字符串。

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

re.sub()re模块中的一个函数,用于在字符串中执行替换操作。

其中各参数的含义如下:

  • pattern:表示正则表达式的模式字符串。

  • repl:表示替换的字符串或可调用对象。如果是字符串,那么将使用该字符串替换匹配到的内容;如果是可调用对象,则将匹配到的内容作为参数传递给该对象,然后使用其返回的结果进行替换。

  • string:表示要进行替换操作的字符串。

  • count:表示替换的最大次数。如果不指定该参数,那么将替换所有匹配到的内容。

  • flags:表示正则表达式的匹配模式。

re.sub()函数返回替换后的字符串。

例:

import re
​
s = 'Hello, World!'
s = re.sub('Hello', 'Hi', s)
print(s)

运行结果:

(6)re.compile(pattern, flags=0)

用于编译正则表达式,并返回一个正则表达式对象。

可选参数 flags 是一个位掩码,用于控制正则表达式的匹配方式。

当需要重复使用同一正则表达式时,可以先使用 re.compile() 进行编译,然后使用返回的正则表达式对象进行匹配。

例:

import re
​
# 编译正则表达式
pattern = re.compile(r'\d+')
​
# 使用编译后的正则表达式对象进行匹配
result = pattern.findall('I have 2 apples and 3 oranges')
​
print(result)  

运行结果:

这些函数和方法是在处理正则表达式时经常使用的,通过这些函数和方法,可以方便地对字符串进行模式匹配和替换操作。

4. 重要概念说明

4.1 子表达式(分组)

在Python的正则表达式中,子表达式是指使用小括号 () 包裹起来的一部分表达式。

它们的作用主要有两个:

  • 分组:子表达式可以将多个元素组成一个逻辑分组,以便于在匹配过程中进行重复操作、分析或引用。例如,(abc){2} 表示匹配两个连续的 "abc"。

  • 捕获:子表达式还可以被捕获,以便于在匹配成功后获取到具体的值。捕获的内容可以通过编号或者使用命名分组来引用。

例:

import re
​
# 分组示例
pattern1 = r'(ab)+'
text1 = 'ababab'
matches1 = re.findall(pattern1, text1)
print(matches1)  # 输出: ['ab', 'ab', 'ab']
​
# 捕获示例
pattern2 = r'(\d{3})-(\d{3})-(\d{4})'
text2 = '123-456-7890'
matches2 = re.search(pattern2, text2)
print(matches2.groups())  # 输出: ('123', '456', '7890')

说明:

  • 第一个示例使用了分组 (ab)+ 来匹配连续出现的 "ab",结果为 ['ab', 'ab', 'ab']

  • 第二个示例使用了捕获的技巧来匹配电话号码的区号、中间号码和尾号,捕获的结果通过 groups() 方法获取,结果为 ('123', '456', '7890')

  • 需要注意的是,使用子表达式时可能会增加正则表达式的复杂度,尤其是在多层嵌套或者涉及到回溯的情况下。

  • 在编写复杂的正则表达式时,建议合理使用子表达式、量词和逻辑运算符等技巧,以提高正则表达式的性能和可读性。

例:

re.search(r'\d(\d)(\d)', 'abcdef123ghijklmn')

说明:

  • Python正则表达式前的 r 表示原生字符串(rawstring),该字符串声明了引号中的内容表示该内容的原始含义,避免了多次转义造成的反斜杠困扰。

  • 正则表达式中\d(\d)(\d)中,(\d)(\d)就是子表达式,一共有两个()圆括号,则代表两个子表达式。

4.2 捕获

捕获指的是在正则表达式中使用小括号 () 将匹配的部分包裹起来,以便后续引用或处理这部分内容。捕获的内容可以使用编号或命名分组进行引用。

在正则表达式的匹配过程中,当一个子表达式匹配到相应的内容后,计算机系统会自动将匹配到的内容保存在一个特定的数据结构中,通常称为捕获组的缓存区。

在 Python 中,通过 re 模块进行正则表达式的匹配,可以通过 group(n) 方法来访问捕获的内容,其中 n 为捕获组的编号。

捕获的语法格式如下:

(pattern)

其中,pattern 是用于匹配的正则表达式模式。

例如,假设有如下的正则表达式:

pattern = r'(\d{2})-(\d{2})-(\d{4})'

当这个正则表达式用于匹配字符串 "31-12-2022" 时,系统会自动将 "31" 放入 $1 缓存区,将 "12" 放入 $2 缓存区,将 "2022" 放入 $3 缓存区。

然后,我们可以使用 group(n) 方法来访问缓存区中的内容,如下所示:

match = re.search(pattern, '31-12-2022')
print(match.group(1))  # 输出: 31
print(match.group(2))  # 输出: 12
print(match.group(3))  # 输出: 2022

需要注意的是,缓存区的编号从 1 开始。在正则表达式中,可以有多个子表达式和多个捕获组,系统会自动为每个捕获组分配一个编号。

4.3 命名分组

命名分组是在正则表达式中为捕获组添加名称的一种方式。

它能够使得引用和处理捕获的内容更加清晰和直观。

命名分组的语法格式如下:

(?P<name>pattern)

其中,name 是你希望为该捕获组指定的名称,pattern 是该捕获组的正则表达式模式。

下面是一个使用命名分组的详细说明和案例:

import re
​
# 使用命名分组匹配手机号码
pattern = r'(?P<area>\d{3})-(?P<exch>\d{3})-(?P<ext>\d{4})'
text = '123-456-7890'
match = re.search(pattern, text)
​
# 获取命名分组的内容
print(match.group('area'))  # 输出: 123
print(match.group('exch'))  # 输出: 456
print(match.group('ext'))  # 输出: 7890

在上述代码中,我们使用了命名分组来匹配手机号码。具体解释如下:

  • (?P<area>\d{3}):定义了一个名为 "area" 的命名分组,匹配3位数字。

  • (?P<exch>\d{3}):定义了一个名为 "exch" 的命名分组,匹配3位数字。

  • (?P<ext>\d{4}):定义了一个名为 "ext" 的命名分组,匹配4位数字。

然后,通过 group('name') 方法可以引用这些命名分组的内容。

使用命名分组能够提高正则表达式的可读性和可维护性,特别适用于复杂匹配的情况。在一个正则表达式中可以有多个命名分组,并且每个命名分组的名称应该是唯一的。

需要注意的是,命名分组只在re模块中的search()match()findall()等方法中才能使用。

4.4 反向引用

反向引用是正则表达式中的一种功能,它允许引用先前捕获的内容。通过反向引用,可以在正则表达式中使用前一个捕获组所匹配到的内容。

反向引用的语法格式如下:

\N

其中,\N 是一个特殊的转义序列,表示引用编号为 N 的捕获组的内容。

下面是一个使用反向引用的详细说明和案例:

import re
​
# 使用反向引用匹配连续相同字符
pattern = r'(\w)\1+'
text = 'Hello! Gooddd morninng!!'
matches = re.findall(pattern, text)
​
# 输出匹配到的连续相同字符
for match in matches:
    print(match)

在上述代码中,我们使用了反向引用来匹配连续相同的字符。具体解释如下:

  • (\w):匹配一个字母、数字或下划线,并进行捕获。

  • \1+:匹配一个或多个与第一个捕获组匹配的内容。

这里的 \1 就是反向引用,表示引用编号为 1 的捕获组,即第一个捕获组。

通过 findall() 方法找到所有匹配的结果,然后遍历输出每个匹配到的连续相同字符。

需要注意的是,反向引用只能在正则表达式中使用,不能在替换字符串的过程中使用。

5. 小结

         ​推荐一个比较好用的网站,正则表达式的匹配规则有很多,很容易记混,只有多加练习才能烂熟于心,用起来才能得心应手。

http://tools.jb51.net/regex/create_reg

标签:字符,匹配,正则表达式,pattern,re,详解,字符串
From: https://blog.csdn.net/qq_67061926/article/details/140287215

相关文章

  • each()详解
    each()方法能使DOM循环结构简洁,不容易出错。each()函数封装了十分强大的遍历功能,使用也很方便,它可以遍历一维数组、多维数组、DOM,JSON等等在javaScript开发过程中使用$each可以大大的减轻我们的工作量。下面提一下each的几种常用的用法each处理一维数组vararr1=["aaa",......
  • Java中的线程池详解
    Java中的线程池详解大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!1.理解线程池的概念在Java中,线程池是一种管理和复用线程的机制,它能够有效地控制并发线程数量,提高系统性能和资源利用率。使用线程池可以避免反复创建和销毁线程的开销,同时能够管理大量......
  • 【转】-CountDownLatch详解
    CountDownLatch详解该博客转载自​爱宝贝丶的​CountDownLatch详解1.简介CountDownLatch中countdown是倒数的意思,latch则是门闩的含义。整体含义可以理解为倒数的门栓,似乎有一点“三二一,芝麻开门”的感觉。CountDownLatch的作用也是如此,在构造CountDownLatch的时候需要传入......
  • Java中的垃圾回收机制详解
    Java中的垃圾回收机制详解大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!Java中的垃圾回收(GarbageCollection,GC)机制是Java虚拟机(JVM)管理内存的一项重要功能。GC机制通过自动回收不再使用的对象所占用的内存,防止内存泄漏,提升应用程序的性能和稳定性。......
  • Linux命令shuf详解:随机排序与数据分析的得力助手
    Linux命令shuf详解:随机排序与数据分析的得力助手引言在Linux系统中,shuf是一个功能强大的命令行工具,用于随机排序、随机抽样和生成随机数。它在数据处理、统计分析以及日常脚本编写中扮演着重要角色。本文将详细介绍shuf命令的基本功能、工作原理、主要参数、应用实例以及......
  • Linux命令skill详解
    Linux命令skill详解引言在Linux系统中,skill命令是一个用于向选定进程发送信号的工具。尽管它不像kill、killall或pkill那样广为人知,但它在管理和控制进程方面同样扮演着重要角色。本文将详细介绍skill命令的基本功能、工作原理、主要特点、使用示例,以及一些注意事项和最佳......
  • 3大主流分布式事务框架详解(图文总结)
    1简要介绍随着微服务架构的不断发展,分布式系统逐渐普及到后端领域的每一个角落。在分布式系统中,跨多个服务的数据一致性一直是一个重大挑战,为解决这一挑战,分布式事务应运而生。作者在之前的文章《五种分布式事务解决方案》和《4大主流分布式算法介绍》中,详细介绍了分布式事物......
  • CSS 选择符及其继承属性详解
    CSS(层叠样式表)是网页设计中不可或缺的一部分,它负责控制网页的样式和布局。CSS选择符是CSS规则的核心,用于选择HTML元素并应用样式。本文将详细介绍CSS选择符的种类,并探讨哪些CSS属性是可以继承的。1.CSS选择符的种类CSS选择符用于选择HTML元素,以便为其应用样式......
  • Linux系统编程-文件相关操作使用详解
    1.文件描述符文件描述符(FileDescriptor)是操作系统中用于访问和操作文件或输入输出资源的一个抽象指针。它是一个非负整数,标识一个已经打开的文件或输入输出资源(如管道、网络连接等)。在UNIX和类UNIX系统(如Linux)中,文件描述符是非常重要的概念,用于文件操作、进程间通信、网络编......
  • Franak Robot State详解
    机器人状态以1kHz的速率提供机器人传感器读数和估计值。它提供:关节级信号:电机和估计的关节角度及其导数、关节扭矩和导数、估计的外部扭矩、关节碰撞/接触。笛卡尔级信号:笛卡尔位姿、配置的末端执行器和负载参数、作用于末端执行器的外部扳手、笛卡尔碰撞。接口信号:最后的......