1 正则表达式的概念
正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为 regex 、regexp 或 RE),是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为元字符)。
正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本。许多程序设计语言都支持利用正则表达式进行字符串操作。正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符及这些特定字符的组合,组成一个规则字符串,这个规则字符串用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,该模式描述在搜索文本时要匹配的一个或多个字符串。
1.1 正则表达式的作用和应用场景
正则表达式的主要作用包括文本的检索、替换以及从一个字符串中提取出符合特定条件的子串。它描述了一种字符串匹配的模式,可以用来检查一个字符串是否含有某种子串、将匹配的子串做替换或者从某个字符串中取出符合某个条件的子串等。
正则表达式的应用场景非常广泛,包括但不限于以下几个方面:
(1)Web开发: 在Web开发中,正则表达式被广泛应用于表单验证、URL处理、数据提取等方面。例如,可以使用正则表达式来验证用户输入的邮箱地址是否符合规范格式。
(2)服务器日志分析: 服务器日志通常包含大量的信息,使用正则表达式可以方便地提取和分析日志数据中的关键信息。
(3)网页爬虫: 正则表达式可以用于解析和处理网页上的文本数据,提取出需要的信息。
(4)文件批量处理: 在处理大量文件时,可以使用正则表达式来快速高效地查找与分析字符串。
此外,正则表达式还被应用于数据验证、信息校验、字符串格式化与美化、以及与其他技术的结合如人工智能和大数据处理等领域。
1.2 C++ 与正则表达式
C++ 与正则表达式的关系主要体现在 C++ 标准库提供的正则表达式支持,这使得在 C++ 程序中使用正则表达式变得更加方便和高效。
从 C++11 开始,C++ 标准库引入了<regex>头文件,其中包含了处理正则表达式的类和函数。这些类和函数使得开发者可以在 C++ 程序中方便地使用正则表达式进行文本匹配、搜索、替换等操作。
C++ 标准库中的正则表达式功能主要包括:
(1)std::regex类: 表示一个正则表达式对象,用于存储和编译正则表达式模式。
(2)std::smatch类: 表示正则表达式匹配的结果,用于存储匹配到的子表达式信息。
(3)std::sregex_iterator类: 是一个迭代器,用于遍历字符串中所有与正则表达式匹配的子串。
(4)正则表达式操作函数:
std::regex_match:检查整个字符串是否与正则表达式匹配。
std::regex_search:在字符串中搜索与正则表达式匹配的子串。
std::regex_replace:替换字符串中与正则表达式匹配的子串。
std::regex_split:根据正则表达式将字符串分割成多个子串。
使用 C++ 标准库中的正则表达式功能,可以执行各种复杂的文本处理任务,如验证输入格式、提取数据、文本替换等。
如下是一个验证字符串是否符合电子邮件地址的格式的样例:
#include <iostream>
#include <regex>
#include <string>
int main()
{
std::string email = "example@example.com";
std::regex emailRegex(R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})");
if (std::regex_match(email, emailRegex))
{
std::cout << "valid email address" << std::endl;
}
else
{
std::cout << "invalid email address" << std::endl;
}
return 0;
}
上面代码的输出为:
valid email address
在上面代码中,定义了一个正则表达式模式来匹配电子邮件地址,并使用 std::regex_match 函数来检查给定的字符串是否符合这个模式。如果匹配成功,输出"valid email address",否则输出"invalid email address"。
2 正则表达式基础语法
正则表达式由一系列普通字符和特殊字符(也被称为是元字符)组成,它们赋予了正则表达式强大的模式匹配能力。
2.1 字符类
在正则表达式中,字符类(也称为字符集合)允许匹配一个字符集合中的任意一个字符。字符类是由方括号 [] 包围的,其中可以包含一系列字符、范围或特殊的转义序列。
以下是一些正则表达式字符类,以及相应的样例:
(1)基本字符类: 匹配方括号内列出的任意一个字符。
样例:[abc] 会匹配字符 “a”、“b” 或 “c”。
(2)字符范围: 在方括号内使用连字符 - 来指定字符范围。
样例:[a-z] 会匹配任意小写字母。
(3)排除字符类: 在方括号内使用 ^ 符号作为第一个字符来排除列出的字符。
样例:[^0-9] 会匹配任意非数字字符。
(4)特殊字符类:
.(点号) 匹配任何单个字符(除了换行符 \n)。
\d 匹配任意数字,等价于 [0-9]。
\D 匹配任意非数字字符,等价于 [^0-9]。
\w 匹配任意字母、数字或下划线,等价于 [a-zA-Z0-9_]。
\W 匹配任意非字母、非数字和非下划线字符,等价于 [^a-zA-Z0-9_]。
\s 匹配任意空白字符,包括空格、制表符、换行符等。
\S 匹配任意非空白字符。
样例:
\d 会匹配字符 “1” 或 “2”。
\w 会匹配字符 “a”、“A”、“1” 或 “_”。
(5)预定义字符类: 某些正则表达式引擎提供了预定义的字符类,如 [:alpha:](字母)、[:digit:](数字)等。这些类可能因不同的引擎而有所不同。
(6)Unicode 字符类: 使用 \u 或 \U 后跟 Unicode 码点来匹配特定的 Unicode 字符或字符范围。
样例:\u0041-\u005A 会匹配任意大写英文字母(A-Z)。
(7)否定字符类: 在字符类的开始处使用 ^ 符号可以表示否定,即匹配不在字符类中的任意字符。
样例:[^aeiou] 会匹配任意非元音字母。
2.2 限定符与量词
正则表达式中的限定符和量词用于指定模式中的元素可以出现的次数。它们提供了强大的控制能力,可以精确地描述和匹配特定模式的文本。
以下是一些常见的正则表达式限定符和量词,以及相应的样例:
(1)*(星号): 匹配前面的元素零次或多次。
样例:zo* 会匹配 “z” 以及 “zoo”,因为 “o” 可以出现零次(即没有 “o”)或多次(如 “oo”)。
(2)+(加号): 匹配前面的元素一次或多次。
样例:zo+ 会匹配 “zo” 以及 “zoo”,但不会匹配 “z”,因为 “o” 必须至少出现一次。
(3)?(问号): 匹配前面的元素零次或一次。
样例:do(es)? 会匹配 “do” 或 “does” 中的 “do”,因为 “es” 可以出现零次(即 “do”)或一次(即 “does”)。
(4){n}: 匹配前面的元素恰好 n 次。
样例:o{2} 会匹配 “oo”,因为 “o” 必须恰好出现两次。
(5){n,}: 匹配前面的元素至少 n 次。
样例:o{2,} 会匹配 “oo”、“ooo”、“oooo” 等,因为 “o” 至少出现两次,可以出现更多次。
(6){n,m}: 匹配前面的元素至少 n 次,但不超过 m 次。
样例:o{2,3} 会匹配 “oo” 和 “ooo”,但不会匹配 “o” 或 “oooo”,因为 “o” 的出现次数必须在 2 到 3 次之间。
这些限定符和量词可以与其他正则表达式元素(如字符、字符组、捕获组等)结合使用,以构建复杂的匹配模式。注意:在实际使用时,正则表达式引擎会根据模式从左到右的顺序进行匹配,并尽量多地匹配字符,这称为贪婪模式。如果希望尽量少的匹配字符,可以使用非贪婪模式(通过在限定符或量词后面加上 ? 来实现)。
2.3 定位符与锚点
正则表达式中的定位符(也称为锚点)用于规定匹配模式在目标对象中的出现位置。这些定位符不会消耗字符,只是指定模式必须出现在字符串的特定位置。
以下是一些常见的正则表达式定位符和锚点,以及相应的样例:
(1)^(脱字号): 匹配输入字符串的开始位置。
样例:^hello 会匹配以 “hello” 开头的字符串,如 “hello world”。
(2)$(美元符号): 匹配输入字符串的结束位置。
样例:world$ 会匹配以 “world” 结尾的字符串,如 “hello world”。
(3)\b(单词边界): 匹配一个单词的的边界位置,即单词字符(如字母、数字、下划线)和非单词字符(如空格、标点符号等)之间的位置。
样例:\bcat\b 会匹配独立的单词 “cat”,而不会匹配 “concatenate” 中的 “cat”。
(4)\B(非单词边界): 匹配非单词边界的位置,即两个单词字符之间或两个非单词字符之间的位置。
样例:\Bcat\B 会匹配 “concatenate” 中的 “cat”,但不会匹配独立的单词 “cat”。
(5)\A(绝对开头位置): 仅匹配字符串的绝对开头位置,忽略多行模式中的换行符
样例:在多行模式下,\Ahello 只会匹配第一行以 “hello” 开头的字符串。
(6)\Z(绝对结尾位置): 仅匹配字符串的绝对结尾位置,忽略多行模式中的换行符
样例:在多行模式下,world\Z 只会匹配最后一行以 “world” 结尾的字符串。
(7)\z(结尾位置): 匹配字符串的结尾位置,不考虑多行模式
样例:\z 在任何模式下都会匹配字符串的结尾位置。
这些定位符和锚点可以帮助精确地指定模式在字符串中的位置,从而实现更准确的匹配。注意:在不同的正则表达式引擎和编程语言中,这些定位符和锚点的行为可能略有不同。
2.4 分组(捕获组)与选择结构
正则表达式中的分组与选择结构是构建复杂模式的重要工具。分组允许将一部分模式组合起来,作为一个整体进行处理,而选择结构则允许指定多个可能的匹配选项。
(1)分组(捕获组):
分组也称为捕获组,是使用圆括号 () 来实现。分组不仅可以对模式进行组合,还可以用于捕获匹配的子串,以便后续引用。
样例:
基本分组:将模式组合成一个整体。 (abc) 这个模式会匹配字符串 “abc” 中的 “abc”。
捕获分组:通过分组捕获匹配的子串。 (\d{3})-(\d{3})-(\d{4}) 这个模式会匹配形如 “123-456-7890” 的字符串

本文介绍了正则表达式的概念、作用、应用场景,以及 C++ 标准库对其的支持。详细阐述了正则表达式的基础语法,包括字符类、限定符、定位符等,还介绍了高级特性,如贪婪匹配、前瞻断言等。最后讲解了 C++ 中 std::regex 等相关类和函数的使用。
3840

被折叠的 条评论
为什么被折叠?



