Byte Regex与C 的Boost匹配

Byte regex matching with Boost in C++

本文关键字:Boost 匹配 Regex Byte      更新时间:2023-10-16

我正在使用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数组视为无效的字符串,并将所有内容都超过0x00regex_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数组是最简单的解决方案。