2011-07-09 8 views
2

以下のコードは、特定のパターンのファイルを検索しています。このコードに追加できる可能性がありますので、4つのパターンを検索する可能性があります。それは最初のものと一致しない場合C#Pattern Search

だから、それはそれは

多くの感謝を二番目に一致するというように....どうかを確認します。 *

byte[] pattern = new byte[5] { 00, 00, 00, 08, 00 }; 
byte[] file = File.ReadAllBytes("C:\\123.cfg"); 

var result = Enumerable.Range(0, file.Length - pattern.Length + 1) 
       .Where(i => pattern.Select((b, j) => new { j, b }) 
            .All(p => file[i + p.j] == p.b)) 
       .Select(i => i + pattern.Length - 1); 

int[] PatternArray = result.ToArray(); 

** * ** ** * ** EDIT ** ** * ** * ** *

プログラムIを実行しているときこれは

response Count = 6 System.Collections.Generic.List<int[]> 
    [0] {int[1]} int[] 
     [0] 1577 int 
    [1] {int[0]} int[] 
    [2] {int[0]} int[] 
    [3] {int[0]} int[] 
    [4] {int[0]} int[] 
    [5] {int[6]} int[] 
     [0] 31 int 
     [1] 246 int 
     [2] 448 int 
     [3] 663 int 
     [4] 864 int 
     [5] 1734 int 

パターンの結果は、すべてがそこにあるように見えることが報告されたものです....配列が保存されたものを参照するには、ブレークポイントを挿入、私は右、これは二次元配列であることを考えていますか?もしあれば、とにかく私はそれを一つの配列に入れることができますか?

感謝

+1

これはstigtforwardよりも優れた方法です1-1一致http://en.wikipedia.org/wiki/String_searching_algorithm – driushkin

+0

ウイルススキャナはどのように進んでいますか? ;) –

答えて

3

バイト[]と「マッチした」ブールの配列(またはリスト...または他の列挙)を作成し、このようなあなたのパターンの検索を中心にwhileループを実行します。

List<byte[]> patterns = new List<byte[]>() 
{ 
    new byte[] { 00, 00, 00, 08, 00 }, 
    new byte[] { 00, 00, 00, 08, 01 }, 
    new byte[] { 00, 00, 00, 08, 02 }, 
    new byte[] { 00, 00, 00, 08, 03 } 
}; 

//bool matched = false; 
foreach (byte[] pattern in patterns) 
{ 
    //while (!matched) 
    //{ 
    byte[] file = File.ReadAllBytes("C:\\123.cfg"); 

    var result = Enumerable.Range(0, file.Length - pattern.Length + 1) 
        .Where(i => pattern.Select((b, j) => new { j, b }) 
             .All(p => file[i + p.j] == p.b)) 
        .Select(i => i + pattern.Length - 1); 

    int[] PatternArray = result.ToArray(); 
    // if (result != null) 
    //  matched = true; 
    //} 
} 

[編集]これはリストとして有効な一致のすべてを返す関数です:

public List<int[]> doPatternSearch() 
     { 

      List<byte[]> patterns = new List<byte[]>() { 
       new byte[] { 00, 00, 00, 08, 00 }, 
       new byte[] { 00, 00, 00, 08, 01 }, 
       new byte[] { 00, 00, 00, 08, 02 }, 
       new byte[] { 00, 00, 00, 08, 03 } 
       }; 
      //this becomes a container to hold all of the valid results 
      List<int[]> response = new List<int[]>(); 

      foreach (byte[] pattern in patterns) 
      { 
       byte[] file = File.ReadAllBytes("C:\\123.cfg"); 

       var result = Enumerable.Range(0, file.Length - pattern.Length + 1) 
         .Where(i => pattern.Select((b, j) => new { j, b }) 
             .All(p => file[i + p.j] == p.b)) 
         .Select(i => i + pattern.Length - 1); 

       if (result != null) 
       { 
        //if the result is not null then add it to the list. 
        response.Add(result.ToArray<int>()); 
       } 
      } 

      return response; 

     } 
+0

"00、00、00、08、00"と一致するものが見つかった場合は何らかの理由で返事をしてくれてありがとうございます。 – user826436

+0

「最初のものと一致しない場合は、それが2番目のものと一致するかどうかを確認する」などと言ったとき、それはあなたがそれを求めていると思ったものです。 boolにマッチした...コードを削除すると、1つのマッチを見つけた後も停止しなくなります。 –

+0

ああ、申し訳ありません...私はbool matched = falseを削除すると、 ... whileループで問題が発生する – user826436

0

ORegexはかなりあなたのためにこれを行うことができます。 バイトシーケンス内のパターンの検索と少し例:

var oregex = new ORegex<byte>("{0}{1}{2}", x=> x==12, x=> x==3, x=> x==5); 
var toSearch = new byte[]{1,1,12,3,5,1,12,3,5,5,5,5}; 
           ^^^^^^ ^^^^^^ 
var foundTwoMatches = oregex.Matches(toSearch); 

またIComparableをオブジェクトを定義することができますし、labmda機能を使用せずに、それを直接渡します。

その他の例here