【CS知识点】一文搞懂 正则表达式

计算机干货知识点,点点关注不迷路!

你是否好奇计算机如何进行数据验证、信息提取还是文本替换?

本文将带你彻底搞懂正则表达式,让你从此掌握一把利器!


目录

基本语法

单个字符匹配

字符集匹配

重复匹配

位置匹配

选择匹配

分组和捕获

分组和捕获

分组

捕获

反向引用

贪婪匹配与懒惰匹配

贪婪匹配

懒惰匹配

零宽断言

应用场景

实例:微信号匹配


       在数字时代,文本数据无处不在,从简单的日志文件到复杂的网页内容,文本处理成为了每个开发者必须面对的挑战。在这些挑战中,正则表达式(Regular Expression,简称 regex)有强大的文本匹配和处理能力,无论是数据验证、信息提取还是文本替换,正则表达式都能提供简洁而高效的解决方案。

基本语法

      正则表达式的核心在于其独特的语法,它使用一系列特殊字符和符号来定义搜索模式。这些特殊字符被称为元字符,它们赋予了正则表达式强大的匹配能力。下面我们将介绍一些最常用的元字符及其功能:

单个字符匹配

.(点号): 匹配任意单个字符(除了换行符)。例如,正则表达式 a.c 可以匹配 "abc"、"aac"、"acc" 等字符串。

\(反斜杠): 用于转义字符,使其失去特殊含义。例如,如果你想匹配一个实际的点号,你需要使用 \.

字符集匹配

[](方括号): 匹配方括号内任意一个字符。例如,[abc] 可以匹配 "a"、"b" 或 "c"。

-(连字符): 在方括号内使用,表示字符范围。例如,[a-z] 匹配所有小写字母,[0-9] 匹配所有数字。

^ (脱字符,[]中): 在方括号内使用,表示否定,即匹配不在方括号内的字符。例如,[^abc] 匹配除了 "a"、"b" 和 "c" 之外的任何字符。

\d: 匹配任何数字,等价于 [0-9]

\D: 匹配任何非数字字符,等价于 [^0-9]

\w: 匹配任何字母、数字或下划线,等价于 [a-zA-Z0-9]

\W: 匹配任何非字母、数字或下划线字符,等价于 [^a-zA-Z0-9]

\s: 匹配任何空白字符,包括空格、制表符、换行符等。

\S: 匹配任何非空白字符

重复匹配

* (星号): 匹配前面的字符 零次或多次。例如,ab*可以匹配 "a"、"ab"、"abb"、"abbb" 等。

+(加号): 匹配前面的字符 一次或多次。例如,ab+可以匹配 "ab"、"abb"、"abbb" 等,但不能匹配 "a"。

?(问号): 匹配前面的字符 零次或一次。例如,ab?可以匹配 "a" 或 "ab"。

{n}: 匹配前面的字符 恰好 n 次。例如,a{3}匹配 "aaa"。

{n,}: 匹配前面的字符 至少 n 次。例如,a{2,}匹配 "aa"、"aaa"、"aaaa" 等。

{n,m}: 匹配前面的字符 至少 n 次,至多 m 次。例如,a{2,4}匹配 "aa"、"aaa" 或 "aaaa"。

位置匹配

^ (脱字符,不在[]中): 匹配字符串的开头。例如,^abc 匹配以 "abc" 开头的字符串。

$ (美元符号): 匹配字符串的结尾。例如,abc$ 匹配以 "abc" 结尾的字符串。

\b: 匹配单词边界。例如,\bcat\b 匹配 "cat" 这个单词,但不匹配 "category" 中的 "cat"。

选择匹配

|(竖线): 表示的关系,匹配左边或右边的表达式。例如,cat|dog 匹配 "cat" 或 "dog"。

分组和捕获

() (圆括号): 将表达式分组,并捕获匹配的子字符串。例如,(ab)+ 匹配 "ab"、"abab"、"ababab" 等,并将每个 "ab" 捕获到一个组中。

       下面是一个python程序实例:

import re

# 匹配以 "a" 开头,以 "b" 结尾的字符串
pattern = r"^a.*b$"
text = "a123b"
match = re.match(pattern, text)
if match:
    print("匹配成功!")
else:
    print("匹配失败!")

分组和捕获

       在正则表达式中,分组捕获是两个非常重要的概念,它们允许我们将匹配的子字符串提取出来,以便进行进一步的处理或分析。

分组

       分组是指使用圆括号 () 将正则表达式的一部分括起来,形成一个子表达式。

分组的作用有:

提高可读性: 将复杂的正则表达式分解成更小的、更易于理解的单元。

应用量词: 对分组内的子表达式应用量词,例如 (ab)+ 匹配 "ab"、"abab"、"ababab" 等。

捕获匹配内容: 将分组内匹配的子字符串捕获到捕获组中,以便后续使用。

捕获

       分组后,我们可以捕获分组内容,进行下一步操作。

捕获组: 默认情况下,每个分组都是一个捕获组,它会将匹配的子字符串捕获到一个编号的组中。例如,正则表达式 (\d{3})-(\d{4}) 匹配 "123-4567" 时,会将 "123" 捕获到第 1 组,将 "4567" 捕获到第 2 组。

非捕获组: 如果你只想对子表达式进行分组,而不需要捕获匹配内容,可以使用非捕获组 (?:)。例如,正则表达式  (?:\d{3})-(\d{4}) 匹配 "123-4567" 时,只会将 "4567" 捕获到第 1 组。

 例:

import re

# 匹配电话号码,并提取区号和号码
pattern = r"(\d{3})-(\d{4})"
text = "我的电话号码是 123-4567。"
match = re.search(pattern, text)
if match:
    print("区号:", match.group(1))  # 输出: 区号: 123
    print("号码:", match.group(2))  # 输出: 号码: 4567

反向引用

       反向引用是指在同一正则表达式中,引用前面捕获组捕获的内容

反向引用的语法是 \n,其中 是捕获组的编号。

       例如,正则表达式 (\d{3})-\1 匹配 "123-123",但不匹配 "123-456"。

贪婪匹配与懒惰匹配

       在正则表达式中,贪婪匹配懒惰匹配是两种不同的匹配模式,它们决定了正则表达式引擎在匹配文本时的行为方式。理解这两种模式的区别对于编写高效、准确的正则表达式至关重要。

贪婪匹配

贪婪匹配是正则表达式的默认匹配模式。在这种模式下,正则表达式引擎会尽可能多地匹配字符,直到无法匹配为止。

例如,正则表达式 a.*b 匹配以 "a" 开头,以 "b" 结尾的字符串。对于字符串 "aabab",贪婪匹配会匹配整个字符串 "aabab"。

懒惰匹配

懒惰匹配与贪婪匹配相反,它会尽可能少地匹配字符,直到满足匹配条件为止。

在正则表达式中,可以使用 ? 来将贪婪匹配转换为懒惰匹配。例如,正则表达式 a.*?b 匹配以 "a" 开头,以 "b" 结尾的字符串,但会尽可能少地匹配字符。对于字符串 "aabab",懒惰匹配会匹配 "aab" 和 "ab" 两个子字符串

例:

import re

# 贪婪匹配
pattern_greedy = r"a.*b"
text = "aabab"
match_greedy = re.search(pattern_greedy, text)
print("贪婪匹配:", match_greedy.group())  # 输出: 贪婪匹配: aabab

# 懒惰匹配
pattern_lazy = r"a.*?b"
match_lazy = re.findall(pattern_lazy, text)
print("懒惰匹配:", match_lazy)  # 输出: 懒惰匹配: ['aab', 'ab']

零宽断言

       在正则表达式中,零宽断言(Zero-width Assertions)是一种特殊的语法结构,它用于指定匹配发生的位置,而不会消耗任何字符。这意味着零宽断言只用于判断某个位置是否满足条件,而不会影响匹配结果的长度

前瞻断言(Lookahead Assertions): 判断当前位置后面是否满足/不满足某个条件。

正向前瞻断言(Positive Lookahead): (?=)

例如,\d+(?=px) 匹配后面跟着 "px" 的数字,例如 "16px" 中的 "16"。

负向前瞻断言(Negative Lookahead): (?!)

例如,\d+(?!px) 匹配后面不跟着 "px" 的数字,例如 "16pt" 中的 "16"。

后瞻断言(Lookbehind Assertions): 判断当前位置前面是否满足/不满足某个条件

正向后瞻断言(Positive Lookbehind):  (?<=)

例如,(?<=\$)\d+ 匹配前面有"$"的数字,例如""的数字,例如"$100" 中的 "100"。

负向后瞻断言(Negative Lookbehind): (?<!)

例如,(?<!\$)\d+ 匹配前面没有 "$" 的数字,例如 "100" 中的 "100"。

应用场景

提取特定位置的文本: 例如,提取 HTML 标签中的内容,可以使用正向后瞻断言和正向前瞻断言。

验证字符串格式: 例如,验证密码强度,可以使用零宽断言来确保密码包含大小写字母、数字和特殊字符。

排除特定模式: 例如,排除包含特定单词的文本,可以使用负向前瞻断言。

实例:微信号匹配

       微信号的规则为:6至20位,以字母开头,后面的字符可以是字母,数字,减号,下划线。

       则我们使用以下正则表达式来匹配:

/^[a-zA-Z][-_a-zA-Z0-9]{5,19}$/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值