一、基础知识
正则表达式是一种用于匹配、搜索和编辑文本的字符串模式。它由一系列字符和特殊符号构成,可以灵活地表达文本的模式、结构和特征。正则表达式在各种编程语言和应用程序中广泛应用,包括C++。它可以用来在文本中查找特定模式的字符串、验证输入的格式、提取信息和进行文本替换等操作。
正则表达式的基本元素包括普通字符(如字母、数字和符号)、特殊字符(如通配符、边界符和量词)以及捕获组和反向引用等高级功能。通过组合这些元素,可以构建复杂的匹配规则,实现强大的文本处理功能。
C++中使用正则表达式的优势:
-
强大的文本处理能力:正则表达式提供了灵活的方式来描述文本模式和规则,能够轻松地实现复杂的文本匹配、搜索和提取功能。
-
通过正则表达式,可以快速验证用户输入的数据格式是否符合要求,提高了数据的准确性和一致性。
-
正则表达式可以轻松地进行文本替换和格式化操作,例如批量替换文本中的内容或者格式化输出文本。
-
正则表达式可以用较短的代码实现复杂的文本处理功能,提高代码的可读性和简洁性。
-
正则表达式可以用于日志分析、数据提取、等各种场景,为 C++ 提供了强大的文本处理工具。
在 C++ 中使用正则表达式,通过提供的<regex>头文件来实现。基本语法和规则:
-
普通字符:包括字母、数字和一些符号,表示自身字符。
-
特殊字符:包括元字符(如
^、$、.、*、+、?、|、\等),用于描述匹配规则。 -
量词:指定前面模式出现的次数,如
*(零次或多次)、+(一次或多次)、?(零次或一次),{m,n}(出现次数范围为m到n次)等。 -
转义字符:使用
\来转义特殊字符,使其成为普通字符。 -
字符类:用 [ ] 表示一组字符中的任意一个。比如 [abc] 匹配 "a"、"b" 或 "c" 中的任意一个。
-
捕获组:用
( )将模式组合成一个单元,可以获取匹配的子串。
在 C++ 的 <regex> 头文件中,常用的类有 std::regex、std::smatch 和 std::regex_match 等,通过这些类可以实现正则表达式的匹配、搜索和提取。例如,使用 std::regex_match 函数来检查一个字符串是否与指定的正则表达式匹配,使用 std::smatch 类来存储匹配的结果。
正则表达式在 C++ 中的基本语法和规则与其他语言中的正则表达式基本相同,但在具体的实现上可能会有一些差异。可查看官方介绍。

二、正则表达式的基本匹配
-
匹配单个字符:
-
使用普通字符进行匹配,例如正则表达式
a可以匹配字符串中的单个字符 "a"。 -
使用元字符
.进行匹配任意单个字符,例如正则表达式s.可以匹配字符串中的 "sa"、"sb"、"sc" 等。
-
-
匹配多个字符:
-
使用量词
*匹配前面的字符出现零次或多次,例如正则表达式ab*可以匹配 "a", "ab", "abb", "abbb" 等。 -
使用量词
+匹配前面的字符出现一次或多次,例如正则表达式ab+可以匹配 "ab", "abb", "abbb" 等。 -
使用量词
?匹配前面的字符出现零次或一次,例如正则表达式ab?可以匹配 "a", "ab" 等。 -
使用花括号
{m,n}匹配前面的字符出现m到n次,例如正则表达式a{2,4}可以匹配 "aa", "aaa", "aaaa"。
-
-
匹配起始和结束位置:
-
使用锚字符
^匹配字符串的起始位置,例如正则表达式^start可以匹配以 "start" 开头的字符串。 -
使用锚字符
$匹配字符串的结束位置,例如正则表达式end$可以匹配以 "end" 结尾的字符串。
-
当使用正则表达式进行文本匹配时,需要匹配字符类(character class)和排除字符类(negated character class)。字符类用来匹配一个字符集合中的任何一个字符,而排除字符类则用来匹配除指定字符集合之外的任何字符。
在正则表达式中使用方括号[]来表示一个字符类,方括号内包含要匹配的字符集合。例如:
-
[aeiou]可以匹配任何一个小写元音字母。 -
[A-Za-z]可以匹配任何一个大写或小写字母。 -
[0-9]可以匹配任何一个数字字符。
另外,可以在方括号内使用连字符-来表示一个范围,如[a-z]表示匹配任何一个小写字母。
相反,使用脱字符^在字符类内表示排除字符类 。例如:[^aeiou] 可以匹配除了小写元音字母之外的任何字符。
正则表达式支持匹配重复出现的模式,使用不同的量词来指定重复匹配的规则。
常用的量词:
-
*:匹配前面的模式零次或多次。 -
+:匹配前面的模式一次或多次。 -
?:匹配前面的模式零次或一次。 -
{n}:匹配前面的模式恰好n次。 -
{n,}:匹配前面的模式至少n次。 -
{n,m}:匹配前面的模式至少n次且至多m次。
例如:
-
a*可以匹配零个或多个 "a"。 -
a+可以匹配一个或多个 "a"。 -
a?可以匹配零个或一个 "a"。 -
a{3}可以匹配恰好三个 "a"。 -
a{2,4}可以匹配两个到四个 "a"。
正则表达式还有两个重要的概念是锚点(anchors)和分组(groups)。
锚点用来指定匹配的位置,常用的锚点:
-
^:匹配字符串的开始位置。 -
$:匹配字符串的结束位置。 -
\b:匹配单词边界。 -
\B:匹配非单词边界。
例如:
-
^abc可以匹配以 "abc" 开头的字符串。 -
xyz$可以匹配以 "xyz" 结尾的字符串。 -
\bword\b可以匹配单独的 "word" 单词。 -
\Bword\B可以匹配 "word" 单词的内部。
分组则用来把对模式的匹配结果进行分组,并对每个分组进行单独的处理。分组用括号()表示。例如:
-
(ab)+可以匹配 "ab"、"abab"、"ababab" 等。 -
(a|b)可以匹配 "a" 或者 "b"。
三、C++中使用正则表达式
-
在C++中使用正则表达式需要包含
<regex>头文件,并使用std命名空间。 -
使用
std::regex类来创建正则表达式对象。正则表达式对象可以用来存储和表示一个特定的正则表达式模式。 -
使用正则表达式来进行匹配和搜索。在C++中使用
std::regex_search函数和std::regex_match函数来实现这些功能。
示例:
展开
代码语言:C++
自动换行
AI代码解释
#include <iostream> #include <regex> int main() { std::string text = "Hello, this is a sample text with some numbers 12345."; std::regex pattern("\\d+"); // 匹配一个或多个数字 std::smatch matches; // 用于存储匹配结果 if (std::regex_search(text, matches, pattern)) { std::cout << "Found match: " << matches.str() << std::endl; } else { std::cout << "No match found." << std::endl; } return 0; }
使用std::regex_search函数来搜索文本text,并且尝试找到与正则表达式模式pattern匹配的内容。还使用了std::smatch类来存储匹配的结果,并打印出匹配的内容。
还可以使用std::regex_match函数来检查整个字符串是否完全匹配正则表达式模式。
代码语言:C++
自动换行
AI代码解释
if (std::regex_match(text, pattern)) { std::cout << "Full match found" << std::endl; } else { std::cout << "No full match found" << std::endl; }
此外,可以使用C++中的正则表达式库来提取和替换匹配的部分 。C++标准库中的std::regex类和std::regex_replace函数可以完成这些任务。
示例:
展开
代码语言:C++
自动换行
AI代码解释
#include <iostream> #include <regex> int main() { std::string text = "The cat sat on the mat."; std::regex pattern("\\b(cat)\\b"); // 匹配整个单词"cat" std::sregex_iterator it(text.begin(), text.end(), pattern); std::sregex_iterator end; for (; it != end; ++it) { std::smatch match = *it; std::cout << "Match found: " << match.str() << " at position " << match.position() << std::endl; } // 替换匹配的部分 std::string replaced_text = std::regex_replace(text, pattern, "dog"); std::cout << "Replaced text: " << replaced_text << std::endl; return 0; }
使用std::sregex_iterator来迭代查找匹配的结果,然后使用std::regex_replace函数来替换匹配的部分。这里还使用了position()函数来获取匹配的位置。
四、高级正则表达式
(1)较为复杂的模式匹配。C++的正则表达式库支持一系列功能强大的正则表达式语法,可以用于更复杂的模式匹配需求,实现更精细的文本匹配和提取。示例:
展开
代码语言:C++
自动换行
AI代码解释
#include <iostream> #include <regex> int main() { std::string text = "The cat sat on the mat. The dog sat on the rug."; std::regex pattern("\\b(\\w+)\\s+sat\\s+on\\s+the\\s+(\\w+)\\b"); // 匹配类似"xxx sat on the xxx"的句子 std::sregex_iterator it(text.begin(), text.end(), pattern); std::sregex_iterator end; for (; it != end; ++it) { std::smatch match = *it; std::cout << "Match found: " << match.str() << std::endl; std::cout << "First captured group: " << match[1].str() << std::endl; std::cout << "Second captured group: " << match[2].str() << std::endl; } return 0; }
(2)使用捕获组和回溯。捕获组允许在正则表达式中标记并捕获特定的部分,而回溯则允许在替换文本中引用捕获的内容。示例:
展开
代码语言:C++
自动换行
AI代码解释
#include <iostream> #include <regex> int main() { std::string text = "The price is $10.99. The total is $25.50."; std::regex pattern("\\$(\\d+\\.\\d+)"); // 匹配美元金额 std::string replaced_text = std::regex_replace(text, pattern, "¥$1"); // 使用捕获组的内容进行替换 std::cout << "Replaced text: " << replaced_text << std::endl; return 0; }
使用了捕获组来匹配金额,并在替换文本中使用了$1来引用捕获的内容进行替换。这里的$1表示使用第一个捕获组的内容来替换匹配的部分。
(3)懒惰匹配与贪婪匹配。懒惰匹配和贪婪匹配用于描述量词的匹配方式。贪婪匹配尽可能多地匹配字符串,而懒惰匹配则尽可能少地匹配字符串。
在C++的正则表达式中使用?来表示懒惰匹配。示例:
展开
代码语言:C++
自动换行
AI代码解释
#include <iostream> #include <regex> int main() { std::string text = "The cat sat on the mat. The dog sat on the rug."; std::regex greedy_pattern("s[a-z]+t"); // 贪婪匹配,尽可能多地匹配s和t之间的字母 std::regex lazy_pattern("s[a-z]+?t"); // 懒惰匹配,尽可能少地匹配s和t之间的字母 std::sregex_iterator it_greedy(text.begin(), text.end(), greedy_pattern); std::sregex_iterator end_greedy; for (; it_greedy != end_greedy; ++it_greedy) { std::smatch match = *it_greedy; std::cout << "Greedy Match found: " << match.str() << std::endl; } std::sregex_iterator it_lazy(text.begin(), text.end(), lazy_pattern); std::sregex_iterator end_lazy; for (; it_lazy != end_lazy; ++it_lazy) { std::smatch match = *it_lazy; std::cout << "Lazy Match found: " << match.str() << std::endl; } return 0; }
贪婪匹配尽可能多地匹配了s和t之间的字母,而懒惰匹配尽可能少地匹配了s和t之间的字母。
(4)向前和向后查找。向前和向后查找提供了一种基于当前匹配位置的相对定位功能,能够查找在特定位置之前或之后的模式。这对于需要匹配特定上下文的情况非常有用。