首页 > 解决方案 > C# 从包含 UTF-8 文本的 byte[] 数组中删除重音符号(变音符号)并进行比较

问题描述

我无法弄清楚如何进行大型 UTF-8 编码文本文件搜索。

我的情况是我有一个需要分析的大量 UTF-8 编码文件,其中包含也有重音字母(不同语言)的文本,然后我有一个特定的查找字符串。

这个查找字符串被转换为一个固定的 byte[] 数组,而源文本文件的内容作为一系列固定长度的数组被加载到内存中。

然后我有一个比较机制,最终归结为这段代码(为了问题而简化):

static int matchesCount = 0;

/// <summary>
/// The inner comparison function
/// </summary>
/// <param name="lookupArrayLength">Length of lookup array</param>
/// <param name="sourceArrayPointer">Source array pointer set to correct position by external loop</param>
/// <param name="lookupArrayPointer">Lookup array pointer set to position zero</param>
static unsafe void compare(int lookupArrayLength, byte* sourceArrayPointer, byte* lookupArrayPointer)
{
    for (int ii = 0; ii < lookupArrayLength; ii++, sourceArrayPointer++, lookupArrayPointer++)
        if (upperLowerCaseMismatch(sourceArrayPointer, lookupArrayPointer))
        {
            //No match, outer loop sets sourceArrayPointer to +1, to move a byte forward
            return;
        }

    //Match found, outer loop sets sourceArrayPointer to +lookupArrayLength
    matchesCount++;
}

static unsafe bool upperLowerCaseMismatch(byte* x1, byte* x2)
{
    return (
    *x1 != *x2 && //exact match
    (*x1 < 65 || *x1 > 122 || //x1 out of alphabet
    *x2 < 65 || *x2 > 122 || //x2 out of alphabet
    *x1 + 32 != *x2) //lowercase match
    );
}

我现在的目标是不仅要比较“不区分大小写”,还要在比较时去掉重音。例如 č => c, ý => y 等。

由于内存和性能原因,我无法将整个输入字符串转换为字符串并将其标准化,由于业务限制,分析必须尽可能快。此外,我不能简单地使用 File.Read(),因为文件非常大,并且在使用这种方法时会出现显着的性能损失和 GC 工作。

我的想法是从 UTF-8 定义的内容开始——第一个字节包含字节数——所以可能基于第一个字节值进行切换,然后读取更多字节,将它们转换为整数并为每个重音字母?

标签: c#arraysstringperformancelookup

解决方案


推荐阅读