天天看点

使用C++ regex库 正则表达式注意事项

背景

最近在做串口程序,遇到一个Win上比较神奇的bug,先与大家分享一下,就是一般情况下,我们打开串口只需要往函数里传输字符串"COMx"(此处的x指代串口号,可以是1~9),如果我们需要用到COM10以上的串口号,程序就会报错,卡在CreateFile函数这里。我查阅了好多资料,才发现原来当串口号是两位数及以上时,函数接收的字符串需要改写成"\\.\COMx",否则就会报错。

于是我想到要编写一个函数能对串口号进行判断,自动处理两位数的串口号。正则表达式这时候派上用场了

C++自带一个regex库,用于正则表达式。

在程序内部输入字符串

在编写C++程序使用到正则表达式的时候,我使用如下代码

std::regex name_scheme("\\\\.\\COM[1-9][:digit:]*");
std::string str = "\\\\.\\COM6";
std::string str1 = "\\\\.\\COM15";
bool rst = std::regex_match(str, name_scheme);
bool rst1 = std::regex_match(str1, name_scheme);
           

得到的rst和rst1结果一直是0,也就是说str和str1一直与正则表达式不匹配。

查阅了好久资料之后找到了问题所在

  • 首先是regex本身会先对字符串做一次转义(将“\\”转义位’’,所以regex处理之后得到的字符串变为了"\\.\COM[1-9][:digit:]*",这时候与str和str1比较就会得到不匹配的结果

    因此,我们要把声明变量写成

如此一来,我们得到的最后的正则表达式就是"\\\\.\\COM[1-9][:digit:]*"

  • 以上处理之后,运行结果是rst为1,rst1为0,与预期不符,解决方法在于我们需要在[:digit:]外再加一个方括号

最终运行结果与预期相符,rst和rst1都是1

从命令行窗口输入字符串

此时,如果str从命令行窗口输入也有要注意的地方:

一开始我是直接输入"\\\\.\\COM5",得到的比较结果是false,我寻思了半天,发现我们从命令行输入"\\\\.\\COM5",存到string变量中变成了"\\\\\\\\.\\\\COM5",如此比较得到的结果自然是false

正确的输入应该是"\\.\COM5",存到string中为"\\\\.\\COM5",就能得到正确的结果了

总结

万变不离其宗,只需要记住我们从窗口输入一个’\’,存到变量中要加上转义符,变成’\\’,而string中的"\\“等价于regex中的”\\\\"(regex本身处理需要转义一次,才得到用于比较的string)

继续阅读