我正在使用Boost Lib进行正则匹配。
我想搜索的输入"字符串"实际上不是字符串,但更多的位图,其中可能包含任何字节。
只要没有输入字符串中的null字节。如果有一个null字节,忽略了所有内容。
如果我替换null字节:
,则此代码有效char* expr = ".*\x08\x00\x27\x47\x6b\xd4.*"
char data[] = {0x12, 0x08, 0x00, 0x27, 0x47, 0x6b, 0xd4, 0x08 }
boost::regex regex = boost::regex(expr);
boost::cmatch what;
if(boost::regex_match(data, what, regex))
//found match
...
else
// failure did not match
...
有人知道如何解决此问题吗?
听起来regex_match()
将您的char
数组视为无效的字符串,并将所有内容都超过0x00
。regex_match()
还将与没有零终端的std::string
类型一起使用。您是否尝试过以这种方式表示数据?
也可以使用Boost Regex匹配二进制文本中的二进制模式。它不会被零字节等控制字符混淆。
boost::regex
构造函数和boost::regex_match
功能有几个过载,例如使用std::string
,迭代量的无效的C弦 - 和 - 超载的迭代器。
由于我们也想匹配零字节,因此我们显然不能使用零端的C线。使用std::string
是可能的(因为它可能包含零字节) - 但是复制图案和文本仅为搜索是浪费的。
迭代器范围非常适合此用例。
示例:
#include <iostream>
#include <boost/regex.hpp>
using namespace std;
int main(int argc, char **argv)
{
const unsigned char expr[] = {
'.', '*', 0x08, 0x00, 0x27, 0x47, 0x6b, 0xd4, '.', '*' } ;
const unsigned char data[] = {
0x12, 0x08, 0x00, 0x27, 0x47, 0x6b, 0xd4, 0x08 };
boost::regex regex(reinterpret_cast<const char*>(expr),
reinterpret_cast<const char*>(expr) + sizeof expr);
boost::cmatch what;
if (boost::regex_match(reinterpret_cast<const char*>(data),
reinterpret_cast<const char*>(data) + sizeof data, what, regex))
cout << "match!n";
else
cout << "no matchn";
return 0;
}
通过例如:
编译$ g++ regex.cc -o regex -Wall -g -lboost_regex
示例输出:
$ ./regex
match!
reinterpret_cast
S可能看起来很危险,但这都是定义的行为。请注意,将data
数组定义为char
数组不是一个好主意,因为根据体系结构,CHAR可能会被签名或未签名。当它签名时,0xd4
会产生此错误:
error: narrowing conversion of ‘212’ from ‘int’ to ‘char’
inside { } [-Wnarrowing]
试图在字符串文字中使用诸如"xd4"
之类的内容时,预计会发生类似的问题。借助双重闪烁,逃脱的解释是由Boost Regex解释的,很容易混淆:"十六进制逃生序列过早终止"。
因此,仅使用示例中的无符号char数组是最简单的解决方案。