user826436
user826436

Reputation: 245

C# Pattern Search

My code below shows searching through a file for a certain pattern .... Is there anyway that I could possible add to this code so that I could maybe search for a possible of four patterns.

So if it doesn't match the first one then it looks to see if it matches the second one and so on ....

Many thanks.

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 ***********

While running the program I inserted a breakpoint to see what the array was storing .... This is what it reported

    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

The pattern results seem all to be there, am I right thinking that this is a two-dimensional array? ... if so is there anyway I could have it in a single array?

Many thanks

Upvotes: 2

Views: 742

Answers (2)

eocron
eocron

Reputation: 7536

ORegex can pretty much do this for you. A little example with pattern search in byte sequence:

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);

You also can define IComparable object and pass it directly, without using labmda functions.

More examples here.

Upvotes: 0

Cos Callis
Cos Callis

Reputation: 5084

create an array (or list...or other enumerable) of byte[] and a 'matched' boolean and then do a while loop around your pattern search like this:

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

[edit] this is a function that returns all of the valid matches as a list:

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;

        }

Upvotes: 3

Related Questions