1.简介
正则表达式是一种用于描述文本模式的语言,常用于字符串匹配、搜索和替换等操作。
C++11引入<regex>来支持正则表达式。
2.字符规则
正则表达式是一个用于描述字符串模式的语言,可以用于匹配、查找、替换字符串中的文本。在正则表达式中,有一些特殊的字符和规则,需要特别注意。
下面是一些常见的正则表达式中的字符和规则
.:匹配任何一个字符,除了换行符 \n。
*:匹配前面的字符或字符类零个或多个。
+:匹配前面的字符或字符类一个或多个。
?:匹配前面的字符或字符类零个或一个。
[]:匹配括号中的任何一个字符。例如,[abc] 匹配字符 a、b 或 c。
[^]:匹配除了括号中的任何一个字符之外的任何一个字符。
例如,[^abc] 匹配除了字符 a、b 和 c 之外的任何一个字符。
|:表示或。例如,a|b 匹配字符 a 或 b。
():用于分组,可以将多个字符或字符类组合在一起。例如,(ab)+ 匹配一个或多个连续的 ab。
^:表示行首,用于匹配字符串的开头。例如,^abc 匹配以 abc 开头的字符串。
$:表示行尾,用于匹配字符串的结尾。例如,abc$ 匹配以 abc 结尾的字符串。
\d:匹配任何一个数字字符,等价于 [0-9]。
\w:匹配任何一个单词字符,包括字母、数字和下划线,等价于 [a-zA-Z0-9_]。
\s:匹配任何一个空白字符,包括空格、制表符和换行符。
\b:匹配单词边界,即单词和非单词字符之间的位置。
需要注意的是,在正则表达式中,一些字符和符号具有特殊的含义,例如 .、*、+、? 等等,
如果需要匹配这些字符本身,需要使用转义符号 \ 来将其转义,例如 \\.、\\*、\\+、\\? 等等。
除了前面提到的字符和规则之外,正则表达式还有一些高级的用法,可以用于更复杂的文本处理。下面是一些常见的高级用法:
{n,m}:匹配前面的字符或字符类至少 n 次,最多 m 次。例如,a{2,3} 匹配两个或三个连续的字符 a。
{n,}:匹配前面的字符或字符类至少 n 次。例如,a{3,} 匹配三个或更多连续的字符 a。
{,m}:匹配前面的字符或字符类最多 m 次。例如,a{,3} 匹配零个、一个、两个或三个连续的字符 a。
():用于捕获分组,将一个或多个字符分为一组,可以将匹配的结果存储到一个变量中。
例如,([a-z]+) 匹配一个或多个小写字母,并将结果存储到一个变量中。
(?:):用于非捕获分组,可以将多个字符或字符类组合在一起,但不会将结果存储到一个变量中。
例如,(?:ab)+ 匹配一个或多个连续的 ab,但不会将结果存储到一个变量中。
(?=):用于正向先行断言,表示前面的字符或字符类必须匹配成功,但不会将其包含在匹配结果中。
例如,\\d+(?=元) 匹配一个或多个数字字符,但只有在其后面紧跟着一个 元 字符时才匹配成功。
(?!):用于负向先行断言,表示前面的字符或字符类必须匹配失败,但不会将其包含在匹配结果中。
例如,\\d+(?!元) 匹配一个或多个数字字符,但只有在其后面不紧跟着一个 元 字符时才匹配成功。
3.使用
在<regex>标准中,最常用的类是std::regex,它表示一个正则表达式对象,std::regex对象可以通过构造函数来创建,并接受一个字符串参数,表示要匹配的正则表达式模式。例如:
std::regex pattern("\\d+");// 匹配一个或多个数字
可以使用std::regex_match、std::regex_search、std::regex_replace等函数对字符串进行正则表达式匹配、搜索和替换等操作。
3.1std::regex_match
std::regex_match函数用于对整个字符串进行匹配,如果匹配成功则返回true,否则返回false.例如
3.2 std::regex_search
std::regex_search函数用于在字符串中搜索匹配项,并返回第一个匹配结果。如果找到匹配项,则返回true,否则返回false.例如:
3.3 std::regex_replace
std::regex_replace函数用于替换字符串中匹配项。例如
3.4 std::smatch类型
std::smatch类型表示一个正则表达匹配结果的集合,当使用std::regex_search或者std::regex_match函数匹配成功时,这些函数会将匹配结果保存在一个std::smatch类型的对象中。std::smatch对象可以通过下标操作符或者迭代器来访问匹配结果。
3.5 std::sregex_iterator
std::sregex_iterator类型表示一个正则表达式匹配结果的迭代器,当使用std::sregex_iterator类型的迭代器遍历结果时,每次迭代器返回一个std::smatch类型的对象,表示一个匹配项
regex pattern(R"(\w+)")表示匹配一个或多个字符,遇到非字符会即完成一次匹配,所以"hello, world"被匹配到两次,一个是"hello"另一个是"world"。
上面的代码中,std::sregex_iterator类型的迭代器it用于遍历字符串中所有单词,并将每个匹配结果保存在std::smatch类型的对象中,然后使用match.str()成员函数来访问匹配结果。
示例
示例1
#include <iostream>
#include <regex>
#include <string>
#include <vector>
using namespace std;
struct ProcessInfo
{
string programName;
int pid;
int fd;
ProcessInfo(string name, int p, int f):
programName(name), pid(p),fd(f){}
};
int main()
{
string processStr = R"((("task1",pid=11700,fd=4),("task2",pid=11800,fd=5),("task1",pid=11900,fd=6)))";
regex pattern(R"(\((\"[^\"]+\",pid=(\d+),fd=(\d+))\))");
sregex_iterator it(processStr.begin(), processStr.end(), pattern);
sregex_iterator end;
vector<ProcessInfo> processes;
while(it != end)
{
smatch match = *it;
string programName = match[1];
int pid = stoi(match[2]);
int fd = stoi(match[3]);
processes.emplace_back(programName, pid, fd);
it++;
}
for(auto proc : processes)
{
cout << "program nam:" << proc.programName
<< ",PID:" << proc.pid
<< ",FD:" << proc.fd
<< endl;
}
return 0;
}
运行结果
该示例用于将字符串“(("task1",pid=11700,fd=4),("task2",pid=11800,fd=5),("task1",pid=11900,fd=6))”中的task名,pid、fd提取出来。
regex pattern(R"(\((\"[^\"]+\",pid=(\d+),fd=(\d+))\))");
匹配模式含义理解,R"()"表示原始字符串字面量;“\(”和"\)"表示匹配括号,括号在在正则表达式中属于特殊字符所以需要使用转义;接下来的"()”表示一个捕获分组; "\""表示匹配双引号,双引号在正则表达式中属于特殊字符所以需要使用转义;"[^\"]+"表示匹配一个或多个非双引号的字符; ",pid="表示匹配字符",pid=";"(\d+)"表示匹配一个或多个数字字符。