C++与正则表达式入门

什么是正则表达式?

正则表达式是一组由字母和符号组成的特殊文本, 当你想要判断许多字符串是否符合某个特定格式;当你想在一大段文本中查找出所有的日期和时间;当你想要修改大量日志中所有的时间格式,在这些情况下,正则表达式都能帮上忙。

简单来说,正则表达式描述了一系列规则,通过这些规则,可以在字符串中找到相关的内容,规则使得搜索的能力更加强大。匹配的过程由正则表达式引擎完成。开发者通常不需要关心正则表达式引擎的实现细节,直接使用其提供的能力即可。

大家可以先想象你正在写一个应用, 然后你想设定一个用户命名的规则, 让用户名包含字符,数字,下划线和连字符,以及限制字符的个数,好让名字看起来没那么丑. 我们使用以下正则表达式来验证一个用户名:

learn-regex

以上的正则表达式可以接受 john_doe , john12_as . 但不匹配 Jo , 因为它包含了大写的字母而且太短了.

本文将以C++语言为例,介绍其中的正则表达式相关知识。

C++中正则表达式的API基本上都位于<regex>头文件中。

部分代码为了简化书写,都已经默认做了以下操作:

#include <iostream> #include <regex> using namespace std; 入门示例

为了使大家有一个直观的感受,文章的开头先通过一些入门示例给大家一个直观的感受。在这个基础之上,再详细讲解其中的细节。

使用正则表达式的大致流程如下:首先你有一段需要处理的文本。这可能是一个字符串对象,也可能是一个文本文件,或者是一大堆日志。接下来你会有特定的目标,例如:找出文本中所有的时间和日期。这个时候你就需要根据可能的格式写出具体的正则表达式,例如,日期的格式是:2020-01-01,那么你的正则表达式可能是这样:\d{4}-\d{2}-\d{2}。(你现在不必纠结与这个正则表达式是什么意思,因为这是本文接下来要讲解的内容。)

有了正则表达式之后,你需要将你的文本和正则表达式交给正则表达式引擎 – 由C++语言(或者其他语言)提供。引擎会在文本中搜索到匹配的结果。这个结果的格式可能是包含了多个组,例如:你可能需要分离出年份和月份。有了引擎返回的结果之后,你就可以进一步处理了。

img

使用正则表达式的流程大体都是一致的,下面是最常见(其他形式大多为其变种)的三种使用方式。

匹配

匹配是判断给定的字符串是否符合某个正则表达式。例如:你想判断当前文本是否全部由数字构成。

下面是一段代码示例:

string s1 = "ab123cdef"; // ① string s2 = "123456789"; // ② regex ex("\\d+"); // ③ cout << s1 << " is all digit: " << regex_match(s1, ex) << endl; // ④ cout << s2 << " is all digit: " << regex_match(s2, ex) << endl; // ⑤

在这段代码中:

这是一个包含了数字和字母的字符串

这是一个只包含了数字的字符串

这是我们的正则表达式,它表示:有多个数字cpp

通过regex_match判断第一个字符串是否匹配,这里将返回false

通过regex_match判断第二个字符串是否匹配,这里将返回true

这段代码输出如下:

ab123cdef is all digit: 0 123456789 is all digit: 1

请注意,正则表达式有它自身的语法。这与C++的语法是两回事。C++编译器只会检查C++代码的语法。因此,即便你的代码通过了C++编译器的语法检查,但在运行的时候,由于正则表达式的语义,还可能出现正则表达式的错误。正则表达式的错看起来类似这样:terminating with uncaught exception of type std::__1::regex_error: The expression contained an invalid escaped character, or a trailing escape.。

搜索

还有一些时候,我们要判断的并非是文本的全体是否匹配。而是在一大段文本中搜索匹配的目标。

下面是一段代码示例,这段示例演示了在一个字符串中查找数字:

string s = "ab123cdef"; // ① regex ex("\\d+"); // ② smatch match; // ③ regex_search(s, match, ex); // ④ cout << s << " contains digit: " << match[0] << endl; // ⑤

这是一个包含了数字和字母的字符串

和前面一样的正则表达式

通过std::smatch来保存匹配的结果。除了std::smatch,还有std::cmatch也很常用。前者是以std::string的形式返回结果,后者是以const char*的形式返回结果。

通过regex_search函数搜索结果

打印出匹配的结果

这段代码输出如下:

ab123cdef contains digit: 123 替换

最后,使用正则表达式的还有一个常见功能是文本替换。很多的编辑器都有这样的功能。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wssgxf.html