.NET字节上的正则表达式而不是字符

bri*_*ner 16 .net c# regex byte boost

我正在尝试使用正则表达式进行一些更容易的解析.

输入是字节的数组(或枚举).

我不想将字节转换为字符,原因如下:

  1. 计算效率
  2. 内存消耗效率
  3. 某些不可打印的字节可能很复杂,无法转换为字符.并非所有字节都是可打印的.

所以我不能使用正则表达式.

我所知道的唯一解决方案是使用Boost.Regex(它在字节上工作--C字符),但这是一个C++库,使用C++/CLI进行包装将需要相当多的工作.

如何直接在.NET中的字节上使用正则表达式,而无需使用.NET字符串和字符?

谢谢.

Tim*_*oyd 8

这里有一些阻抗不匹配.您希望使用.Net中使用字符串(多字节字符)的正则表达式,但您希望使用单字节字符.你不能像往常一样同时使用.Net.

但是,为了打破这种不匹配,你可以以面向字节的方式处理字符串并改变它.然后,变异的字符串可以充当可重用的缓冲区.通过这种方式,您不必将字节转换为字符,也不必将输入缓冲区转换为字符串(根据您的问题).

一个例子:

//BLING
byte[] inputBuffer = { 66, 76, 73, 78, 71 };

string stringBuffer = new string('\0', 1000);

Regex regex = new Regex("ING", RegexOptions.Compiled);

unsafe
{
    fixed (char* charArray = stringBuffer)
    {
        byte* buffer = (byte*)(charArray);

        //Hard-coded example of string mutation, in practice you would
        //loop over your input buffers and regex\match so that the string
        //buffer is re-used.

        buffer[0] = inputBuffer[0];
        buffer[2] = inputBuffer[1];
        buffer[4] = inputBuffer[2];
        buffer[6] = inputBuffer[3];
        buffer[8] = inputBuffer[4];

        Console.WriteLine("Mutated string:'{0}'.",
             stringBuffer.Substring(0, inputBuffer.Length));

        Match match = regex.Match(stringBuffer, 0, inputBuffer.Length);

        Console.WriteLine("Position:{0} Length:{1}.", match.Index, match.Length);
    }
}
Run Code Online (Sandbox Code Playgroud)

使用这种技术,你可以分配一个字符串"buffer",它可以重新用作Regex的输入,但是你可以每次用你的字节改变它.这样可以避免每次要进行匹配时将字节数组编码转换为新的.Net字符串的开销.这可能被证明是非常重要的,因为我已经看到.Net中的许多算法试图以每小时一百万英里的速度通过字符串生成以及随后的堆垃圾邮件和在GC中花费的时间而瘫痪.

显然这是不安全的代码,但它是.Net.

正则表达式的结果会生成字符串,所以这里有一个问题.我不确定是否有一种方法可以使用不会生成新字符串的正则表达式.您当然可以获得匹配索引和长度信息,但字符串生成违反了您对内存效率的要求.

更新

实际上在反汇编Regex\Match\Group\Capture后,看起来它只在访问Value属性时生成捕获的字符串,因此如果您只访问索引和长度属性,则至少不会生成字符串.但是,您将生成所有支持的Regex对象.