无法获得正确的返回索引

时间:2015-07-12 03:33:24

标签: regex streamreader

好吧,首先,我要感谢大家在过去几周里为我提供了这么多帮助,这是另一个人!

我有一个文件,我使用正则表达式来查找术语" 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));
        }

它返回了完全错误的索引点,如图所示

enter image description here

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

我使用Regex与简单的搜索功能,因为每次出现" TamedName"太过庞大,无法编码成函数。

真的希望你们能帮助我解决这个问题:(我已经没想完了!!

1 个答案:

答案 0 :(得分:2)

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

我的代码如下所示。(正如我们的代价,你需要启用不安全的编译来编译代码 - 这是为了快速搜索二进制数组)

为了正确归因,我借SO answer

Dylan 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;
            }
        }    
    }
}