正则表达式
正则表达式(Regular Expression),通常简称为正则或正则表达式,是一种用于描述字符串模式的工具。它是由一系列字符和特殊字符组成的字符串,用于定义搜索模式或进行字符串匹配、替换、提取等操作。
正则表达式提供了一种灵活、强大且通用的方式来处理文本。它可以用于各种编程语言和文本编辑器中,例如Python、Java、JavaScript等,几乎所有语言很多场景都可以用到正则表达式。
使用正则表达式,可以进行以下操作:
- 匹配:检查一个字符串是否与指定的模式匹配。
- 搜索:在一个字符串中搜索满足指定模式的内容。
- 替换:将字符串中满足指定模式的部分替换为其他内容。
- 提取:从一个字符串中提取出满足指定模式的内容。
正则表达式使用一些特殊字符和语法来表示不同的匹配规则,例如:
- 字符匹配:使用普通字符表示匹配该字符本身。
- 字符类:使用方括号 [] 表示匹配指定范围内的字符。
- 量词:使用特殊字符表示匹配字符出现的次数,如 *、+、?、{}。
- 边界匹配:使用特殊字符表示匹配字符串的边界或位置,如 ^、$、\b。
- 分组:使用圆括号 () 表示将一组字符作为一个单元进行匹配或提取。
正则表达式的语法和特性因不同的实现和工具而略有差异,但基本的概念和常用的模式匹配规则是通用的。
学习工具推荐:
下载与安装
你可以使用以下两种方式中的任意一个来下载安装正则表达式测试器,这个工具源文本内容不能输入太多,要么有时候会匹配不成功。
- 安装版
- 下载 Regester安装程序
- 解压后运行 RegesterSetup.zh.exe
- 绿色版
- 下载 Regester
- 解压后运行 Regester.exe
- 如果无法启动,请自行下载安装 Microsoft .Net Framework 4.8 后再试
常见正则表达式命令和参数解释:
-
.
(点号):匹配除换行符外的任意字符。- 示例:
a.b
可以匹配 "aab"、"acb"、"adb" 等,但不匹配 "a\nb"。
- 示例:
-
*
:匹配前面的字符零次或多次。- 示例:
ab*c
可以匹配 "ac"、"abc"、"abbc" 等。
- 示例:
-
+
:匹配前面的字符一次或多次。- 示例:
ab+c
可以匹配 "abc"、"abbc" 等,但不匹配 "ac"。
- 示例:
-
?
:匹配前面的字符零次或一次。- 示例:
ab?c
可以匹配 "ac"、"abc",但不匹配 "abbc"。
- 示例:
-
[]
(字符类):匹配方括号内的任意字符。- 示例:
[abc]
可以匹配 "a"、"b"、"c" 中的任意一个字符。
- 示例:
-
[^]
(否定字符类):匹配不在方括号内的任意字符。- 示例:
[^abc]
可以匹配除了 "a"、"b"、"c" 以外的任意字符。
- 示例:
-
\d
:匹配任意数字字符(0-9)。- 示例:
\d+
可以匹配一个或多个数字字符。
- 示例:
-
\w
:匹配任意字母、数字或下划线字符。- 示例:
\w+
可以匹配一个或多个字母、数字或下划线字符。
- 示例:
-
\s
:匹配任意空白字符(空格、制表符、换行符等)。- 示例:
\s+
可以匹配一个或多个空白字符。
- 示例:
-
^
:匹配字符串的开头。- 示例:
^abc
可以匹配以 "abc" 开头的字符串。
- 示例:
-
$
:匹配字符串的结尾。- 示例:
abc$
可以匹配以 "abc" 结尾的字符串。
- 示例:
-
()
(分组):将字符组合成一个单元,可以对其进行操作。- 示例:
(ab)+
可以匹配 "ab"、"abab"、"ababab" 等。
- 示例:
零宽断言匹配示例:
零宽断言(Zero-width assertions)是正则表达式中的一种特殊语法,用于在匹配过程中对位置进行条件限制,而不匹配实际的字符。它们被称为零宽度断言,因为它们不会消耗字符串中的字符,仅用于确定匹配发生的位置。
零宽断言分为正向断言(Lookahead)和负向断言(Lookbehind)两种类型。正向断言用于指定位置后面的条件,负向断言用于指定位置前面的条件。
-
正向肯定预查(Positive Lookahead):
(?=abc)
:匹配后面紧跟着 "abc" 的位置。- 示例:
a(?=bc)
可以匹配 "a",但只有在后面跟着 "bc" 的情况下才匹配成功。
-
正向否定预查(Negative Lookahead):
(?!abc)
:匹配后面不紧跟着 "abc" 的位置。- 示例:
a(?!bc)
可以匹配 "a",但只有在后面不跟着 "bc" 的情况下才匹配成功。
-
负向肯定预查(Positive Lookbehind):
(?<=abc)
:匹配前面紧跟着 "abc" 的位置。- 示例:
(?<=ab)c
可以匹配 "c",但只有在前面紧跟着 "ab" 的情况下才匹配成功。
-
负向否定预查(Negative Lookbehind):
(?<!abc)
:匹配前面不紧跟着 "abc" 的位置。- 示例:
(?<!ab)c
可以匹配 "c",但只有在前面不跟着 "ab" 的情况下才匹配成功。
贪婪匹配非贪婪匹配
贪婪匹配(Greedy matching)和非贪婪匹配(Non-greedy matching)是正则表达式中量词(匹配内容多还是少)的匹配模式。
贪婪匹配
是指在满足匹配条件的前提下,尽可能多地匹配字符。它会尽量扩展匹配的范围,直到无法再匹配为止。贪婪匹配使用量词 +
、*
、{n,}
等,默认情况下都是贪婪匹配。
例如:正则表达式 a+
会尽量匹配连续重复的字符 "a",直到遇到不是 "a" 的字符为止。
非贪婪匹配
是指在满足匹配条件的前提下,尽可能少地匹配字符。它会尽量缩小匹配的范围,以便允许后续的匹配得到满足。非贪婪匹配使用量词后面添加 ?
来表示。例如,正则表达式 a+?
会匹配尽可能少的连续重复的字符 "a",以满足匹配的条件。
通过比较贪婪匹配和非贪婪匹配,可以更好地控制正则表达式的匹配行为。贪婪匹配通常用于尽可能多地捕获匹配的内容,而非贪婪匹配通常用于尽可能少地匹配,特别是在需要处理嵌套结构或提取特定部分的情况下非常有用。
贪婪匹配示例:
正则表达式:[a-z]+
输入字符串:abcdefg
匹配结果:abcdefg
解释:贪婪匹配会尽可能多地匹配小写字母。在这个示例中,正则表达式 [a-z]+ 匹配了整个字符串 abcdefg,因为它可以匹配一个或多个连续的小写字母。
非贪婪匹配示例:
正则表达式:[a-z]+?
输入字符串:abcdefg
匹配结果:a
解释:非贪婪匹配使用 ? 后缀来指示尽可能少地匹配小写字母。在这个示例中,正则表达式 [a-z]+? 只匹配了第一个小写字母 "a",因为它尽可能少地匹配满足条件的字符。
贪婪匹配和非贪婪匹配的比较:
正则表达式:".+"
输入字符串:"Hello" "World"
匹配结果(贪婪匹配):"Hello" "World"
匹配结果(非贪婪匹配):"Hello"
解释:贪婪匹配会尽可能多地匹配字符,因此 ".+" 会匹配整个字符串 "Hello" "World"。而非贪婪匹配则尽可能少地匹配字符,因此 ".+?" 只匹配了第一个字符串 "Hello"。
贪婪匹配和非贪婪匹配的比较:
正则表达式:[0-9]+
输入字符串:12345
匹配结果(贪婪匹配):12345
匹配结果(非贪婪匹配):12345
解释:无论是贪婪匹配还是非贪婪匹配,正则表达式 [0-9]+ 都会匹配整个字符串 12345,因为它可以匹配一个或多个连续的数字。
正则表达式练习题:
- 匹配邮箱地址:
正则表达式:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
示例输入:example@example.com
^:表示匹配字符串的开头。
\w+:表示匹配一个或多个字母、数字或下划线,这部分匹配了邮箱地址的用户名部分。
([-+.]\w+)*
:表示匹配一个连字符、加号或句点后跟一个或多个字母、数字或下划线的组合,这部分匹配了用户名中的特殊字符及后续字符,可以重复零次或多次。@:表示匹配邮箱地址中的@
\w+:表示匹配一个或多个字母、数字或下划线,这部分匹配了邮箱地址的域名中的名称部分。
([-.]\w+)*
:表示匹配一个连字符或句点后跟一个或多个字母、数字或下划线的组合,这部分匹配了域名中的特殊字符及后续字符,可以重复零次或多次。.:表示匹配邮箱地址中的点号(.),需要使用反斜杠进行转义。
\w+:表示匹配一个或多个字母、数字或下划线,这部分匹配了邮箱地址中的顶级域名部分。
([-.]\w+)*
:表示匹配一个连字符或句点后跟一个或多个字母、数字或下划线的组合,这部分匹配了顶级域名中的特殊字符及后续字符,可以重复零次或多次。$:表示匹配字符串的结尾。
- 匹配手机号码(简化版):
正则表达式:^\d{11}$
示例输入:12345678901
^:表示匹配字符串的开头。
\d:表示匹配一个数字。
{11}:表示前面的元素(即数字)必须连续重复11次。
$:表示匹配字符串的结尾。
- 匹配日期(格式为YYYY-MM-DD):
正则表达式:^\d{4}-\d{2}-\d{2}$
示例输入:2023-08-09
^:表示匹配字符串的开头。
\d:表示匹配一个数字。
{4}:表示前面的元素(即数字)必须连续重复4次,即匹配4位数字的年份。
-:表示匹配连字符。
\d{2}:表示前面的元素(即数字)必须连续重复2次,即匹配2位数字的月份。
-:表示匹配连字符。
\d{2}:表示前面的元素(即数字)必须连续重复2次,即匹配2位数字的日期。
$:表示匹配字符串的结尾。
- 匹配URL(以http或https开头):
正则表达式:^(http|https)://[^\s/$.?#].[^\s]*$
示例输入:https://www.example.com
^:表示匹配字符串的开头。
(http|https):使用括号和竖线(|)表示分组,表示匹配 http 或 https。
😕/:表示匹配 😕/ 字符串。
[^\s/$.?#]
:表示匹配任意不是空白字符、斜杠、问号、点号或井号的字符。.:表示匹配一个任意字符。
[^\s]*
:表示匹配零个或多个任意不是空白字符的字符。$:表示匹配字符串的结尾。
- 匹配整数(包括正负整数):
正则表达式:^-?\d+$
示例输入:-123
^:表示匹配字符串的开头。
-?:表示匹配可选的负号(减号)。- 表示匹配一个负号,? 表示前面的元素(即负号)可选。
\d+:表示匹配一个或多个数字。
$:表示匹配字符串的结尾。
- 匹配英文句子(以句号结尾):
正则表达式:^[A-Z][^.!?]*\.$
示例输入:This is a sentence.
^:表示匹配字符串的开头。
[A-Z]:表示匹配一个大写字母。
[^.!?]*
:表示匹配零个或多个非句号、非问号和非感叹号的字符。这个部分用于匹配句子中除了句号以外的其他内容。.:表示匹配句号。需要使用反斜杠进行转义,因为句号在正则表达式中是一个特殊字符。
$:表示匹配字符串的结尾。
- 匹配HTML标签(包括属性):
正则表达式:<([a-z]+)(\s[a-z]+\s*=\s*"[^"]*")*\s*>.*<\/\1>$
示例输入:<div class="example">This is a div.</div>
匹配结果:匹配成功
<([a-z]+):表示匹配以 < 开始的标签,并捕获标签名。 [a-z]+ 表示匹配一个或多个小写字母。
(\s[a-z]+\s*=\s*"[^"]*")*
:表示匹配零个或多个属性,每个属性由一个或多个小写字母组成的属性名、可选的空白字符、等号、可选的空白字符、以及由双引号包围的属性值组成。这部分用于匹配标签中的属性。
\s*>
:表示匹配以空白字符结尾并以 > 结束的标签起始部分。
.*
:表示匹配零个或多个任意字符,用于匹配标签内的内容。</\1>:表示匹配以 </ 开始、后跟与起始标签相同的标签名、以 > 结束的结束标签。 \1 表示引用第一个捕获组中的标签名。
- 匹配IP地址(简易版):
正则表达式:^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$
示例输入:192.168.0.1
匹配结果:匹配成功
^:表示匹配字符串的开头。
\d{1,3}:表示匹配一个由 1 到 3 位数字组成的部分。
.:表示匹配一个点号(.)。需要使用反斜杠进行转义,因为点号在正则表达式中是一个特殊字符。
.:表示匹配任意字符。
$:表示匹配字符串的结尾。
- 匹配邮政编码(6位数字):
正则表达式:^\d{6}$
示例输入:123456
匹配结果:匹配成功
^:表示匹配字符串的开头。
\d{6}:表示匹配六个连续的数字。
\d:表示匹配一个数字。
{6}:表示前面的元素(即数字)重复出现六次。
$:表示匹配字符串的结尾。
- 匹配用户名(由字母、数字、下划线组成,长度为4-16位):
正则表达式:^[a-zA-Z0-9_]{4,16}$
示例输入:user_123
匹配结果:匹配成功
^:表示匹配字符串的开头。
[a-zA-Z0-9_]:表示匹配一个字母(大小写)、数字或下划线字符。
{4,16}:表示前面的元素(即字母、数字或下划线)重复出现 4 到 16 次,限制了字符串的长度范围。
$:表示匹配字符串的结尾。
我们为什么需要学习正则表达式:
-
文本处理和搜索: 正则表达式是一种强大的工具,可用于在文本中进行搜索、匹配、替换和提取操作。它们可以帮助你快速有效地处理和操纵文本数据。
-
模式匹配和验证: 正则表达式是用于匹配和验证特定模式的工具。你可以使用它们来验证输入数据的格式、匹配特定模式的字符串,例如邮箱地址、URL、电话号码等。
-
编程和脚本语言支持: 正则表达式在许多编程语言和脚本语言中都有广泛的支持,包括 Python、JavaScript、Java、C#等。了解正则表达式可以帮助你在编程中更好地处理字符串操作。
-
文本编辑器和IDE: 许多文本编辑器和集成开发环境(IDE)都支持正则表达式搜索和替换功能。掌握正则表达式可以提高你在编码和文本编辑过程中的效率。
-
数据清洗和提取: 在数据处理和清洗过程中,正则表达式可以帮助你快速提取、筛选和转换数据。它们特别适用于处理大量文本数据或具有特定格式的数据。
-
网络爬虫和数据抓取: 当你需要从网页或其他来源中抓取数据时,正则表达式可以帮助你定位和提取所需的信息。它们是构建简单的网络爬虫和数据抓取工具的有用工具。
学习正则表达式可以提升你在文本处理、模式匹配、数据清洗和编程方面的技能。它们是处理和操作文本的强大工具,广泛应用于软件开发、数据分析、文本处理等领域。掌握正则表达式将为你提供更多的灵活性和能力来处理和操作各种类型的文本数据。