C++ 学习4
基础理论
C++ 中可以用左值引用或者右值引用保存数据吗?
一般不行,除非能确定被引用的对象是长期存在的。
(1) 如果是左值引用可以视具体情况而定,左值引用。
(2) 如果是右值引用,由于被引用的对象是右值,它一般都是"临时对象",更不能长期保存。
class A {......
}class B {
public:A& a; // 不推荐,除非能确定别名a对应的左值生命周期大于本类的生命周期A&& aa; // 不推荐,想不出有什么场景可以适用,经测试会导致编译不过
}
C++实战
boost正则匹配
参考:
基础:https://blog.csdn.net/u012198575/article/details/83624251
详尽:https://blog.csdn.net/ponew/article/details/80348352
regex_match()函数用来判断是否匹配,regex_match要求正则express与串全部匹配时才返回true,否则返回false;
regex_search()函数来搜索字符串中的匹配项,并使用smatch对象来存储匹配结果。regex_search不要求正则express与串完全匹配,但串中内容可以多不能少,即字符串中必须要有定义的正则express才会返回true。
匹配时默认是贪婪模式,可以添加’?‘选择尽可能短的匹配,如’.?';
(?:pattern):匹配pattern但不获取匹配结果;
将上面两个结合起来:(?:.?)这个表达式表示不储存(捕获)结果,并且不贪婪。
表示可以匹配0次或者多次,如果希望至少匹配1次,则不要用,例如用(.?)替换(.*?);
注意:(.)是贪婪匹配,(.?)是非贪婪匹配,比如对于字符串"aaaaa key bbbbbb key":
“(.)key" 捕获的是 "aaaaa key bbbbbb ",能要的我全要,只给你留最后一个。
"(.?)key” 捕获的是"aaaaa ",我不贪婪,只要捕获第一个能满足正则表达式的字符串我就返回。
#include <iostream>
#include <string>
#include <boost/regex.hpp>using namespace std;
using namespace boost;int main()
{string str = "2023-03-28 14:37:52.891 Sessiona,adfadfadf";regex reg("(\\\\d{4}-\\\\d{2}-\\\\d{2})\\\\s(\\\\d{2}:\\\\d{2}:\\\\d{2}\\\\.\\\\d{3})");smatch m;// 注意:只有正则表达式全部满足才会返回true,即定义的格式字符串中必须要有if (regex_search(str, m, reg)) {if {m[1].matched) {cout << "日期内容:" << m[1] << endl;}if {m[2].matched) {cout << "时间内容:" << m[2] << endl;}}string str2 = "2023-03-28 14:37:52.891 Session \\"My-Session-Name\\": xxxxxxxxxx: Client host name: \\"\\", Client IP address: \\"10.2.2.100\\", Client port number: xxxx";regex reg2("Session\\\\s\\"(.*?)\\":.*?Client IP address:\\\\s\\"(.*?)\\"");smatch match2;if (regex_search(str2, match2, reg2)){cout << "session-name:" << match2[1] << endl;cout << "targetIP:" << match2[2] << endl;}return 0;
}
分析reg:
(1) ()表示捕获,要输出到外面的内容;
(2) ‘\\d’即为\\d,表示匹配数字;
(3) ‘\\.’即为‘.’,表示匹配’.‘;(如果没有‘\\’,只有单独的‘.’则表示匹配任意字符)
(4) {4}表示长度必须为4;
(5) ‘\\s’即为\\s,表示匹配空格;
(6) 正则表达式Session\\s"(.*?)“:.Client IP address:\\s"(.?)”,它匹配Session后面的任何内容,然后用‘()’捕获,再继续匹配直到找到’Client IP address’,然后继续用‘()’捕获,获取IP。
另外一个例子,如何匹配"sec_20230413_0737.log"中的日期和时间?
std::string fileName1 = "sec_20230413_0737.log";
boost::regex reg(".*?(\\\\d{1,8})_(\\\\d{1,6})\\\\.log");
boost::smatch m1;
regex_search(fileName1, m1, reg);
注意最前面的.*?
不能改成.*
,否则可能会因为贪婪只能匹配到最后一个数字(期望是能匹配1-8个数字)。