【问题标题】:Can't get the proper Index to return无法获得正确的索引以返回
【发布时间】:2015-07-12 03:33:23
【问题描述】:

好的,首先我要感谢大家在过去几周对我的帮助很大,这是另一个!!!

我有一个文件,我正在使用正则表达式来查找术语“TamedName”出现了多少次。这是最简单的部分:)

原来我是这样设置的

            StreamReader ff = new StreamReader(fileName);
        String D = ff.ReadToEnd();
        Regex rx = new Regex("TamedName");
        foreach (Match Dino in rx.Matches(D))
        {
            if (richTextBox2.Text == "")
                richTextBox2.Text += string.Format("{0} - {1:X} - {2}", Dino.Value, Dino.Index, ReadString(fileName, (uint)Dino.Index));
            else
                richTextBox2.Text += string.Format("\n{0} - {1:X} - {2}", Dino.Value, Dino.Index, ReadString(fileName, (uint)Dino.Index));
        }

它返回完全不正确的索引点,如图所示

我相当有信心我知道它为什么这样做,可能是因为将所有内容从二进制文件转换为字符串,显然并非所有字符都会被翻译,因此会抛出实际的索引计数,因此尝试将其关联起来back 根本不起作用...问题,我不知道如何将正则表达式与二进制文件一起使用并正确翻译:(

我使用的是正则表达式而不是简单的搜索函数,因为每次出现“TamedName”之间的差异太大而无法编码到函数中。

真的希望你们能帮我解决这个问题:(我的想法已经不多了!!

【问题讨论】:

    标签: regex streamreader


    【解决方案1】:

    问题在于您正在读取二进制文件,而流式读取器在将其读入 Unicode 字符串时会进行一些解释。需要按字节处理。

    我的代码如下。(仅供参考,您需要启用不安全编译才能编译代码 - 这是为了快速搜索二进制数组)

    为了正确归属,我从SO answerDylan Nicholson借用了IndexOf的字节版本

    namespace ArkIndex
    {
        class Program
        {
            static void Main(string[] args)
            {
                string fileName = "TheIsland.ark";
                string searchString = "TamedName";
                byte[] bytes = LoadBytesFromFile(fileName);
                byte[] searchBytes = System.Text.ASCIIEncoding.Default.GetBytes(searchString);
    
                List<long> allNeedles = FindAllBytes(bytes, searchBytes);    
            }
    
            static byte[] LoadBytesFromFile(string fileName)
            {
                FileStream fs = new FileStream(fileName, FileMode.Open);
                //BinaryReader br = new BinaryReader(fs);
                //StreamReader ff = new StreamReader(fileName);
    
                MemoryStream ms = new MemoryStream();
                fs.CopyTo(ms);
                fs.Close();
                return ms.ToArray();   
            }
    
            public static List<long> FindAllBytes(byte[] haystack, byte[] needle)
            {
                long currentOffset = 0;
                long offsetStep = needle.Length;
                long index = 0;
                List<long> allNeedleOffsets = new List<long>();
                while((index = IndexOf(haystack,needle,currentOffset)) != -1L)
                {
                    allNeedleOffsets.Add(index);
                    currentOffset = index + offsetStep;
                }
                return allNeedleOffsets;
            }
    
            public static unsafe long IndexOf(byte[] haystack, byte[] needle, long startOffset = 0)
            {
                fixed (byte* h = haystack) fixed (byte* n = needle)
                {
                    for (byte* hNext = h + startOffset, hEnd = h + haystack.LongLength + 1 - needle.LongLength, nEnd = n + needle.LongLength; hNext < hEnd; hNext++)
                        for (byte* hInc = hNext, nInc = n; *nInc == *hInc; hInc++)
                            if (++nInc == nEnd)
                                return hNext - h;
                    return -1;
                }
            }    
        }
    }
    

    【讨论】:

    • 非常感谢我一直在努力解决这个问题,谢谢drive.google.com/…
    • 请问你的速度是多少? +1
    • @frisbee 和我的测试文件,一秒钟左右。不过我并没有真正对其进行基准测试。
    猜你喜欢
    • 2015-11-17
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    • 2018-07-25
    • 1970-01-01
    • 1970-01-01
    • 2017-07-31
    • 1970-01-01
    相关资源
    最近更新 更多