locked
Split string RRS feed

  • Question

  • How can i split this string in order to get the date, hour and every information after the = sign ?

     

     

    2010-07-21 16:36:18 device_id=FG100A3907507008 log_id=0101023010 type=event

    subtype=ipsec pri=error loc_ip=192.158.33.17 loc_port=4500

    rem_ip=200.221.90.436 rem_port=40992 out_if=wan1 vpn_tunnel=dialup_2

    cookies=97f81748ffb1b5af/7c6af4c338e9be44 action=dpd status=dpd_failure

    msg="IPsec DPD detected a failure on the tunnel to 213.00.90.192:40992" 


    I tried using

     

     

     

       string[] s1 = string.Split(new string[] { " " }, StringSplitOptions.None);
       for (int i = 0; i <= 1; i++)
       {
        StreamWriter sw = File.AppendText("D:\\text4.txt");
        sw.WriteLine(s1[i]);
        sw.Close();
       }
    
       for (int i = 2; i <=15 ; i++)
       {
        string[] s2 = s1[i].Split(new string[] { "=" }, StringSplitOptions.None);
        StreamWriter sw = File.AppendText("D:\\text4.txt");
        sw.WriteLine(s2[0]);
        sw.Close();
        
       }
    

     

    but instead of the ipsec and192.158.33.17 i get subtype and rem_ip. 
    I also can't figure out how to obtain the report message "IPsec DPD detected a failure on the tunnel to 213.00.90.192:40992"  .

     

    Wednesday, July 28, 2010 10:39 AM

Answers

  • Hi,

    You can simply use Regex.Split :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.IO;
    
    namespace Test.SplitString
    {
      class Program
      {
        static void Main(string[] args)
        {
          string text = @"2010-07-21 16:36:18 device_id=FG100A3907507008 log_id=0101023010 type=event
                  subtype=ipsec pri=error loc_ip=192.158.33.17 loc_port=4500
                  rem_ip=200.221.90.436 rem_port=40992 out_if=wan1 vpn_tunnel=dialup_2
                  cookies=97f81748ffb1b5af/7c6af4c338e9be44 action=dpd status=dpd_failure
                  msg='IPsec DPD detected a failure on the tunnel to 213.00.90.192:40992'";
    
          string pattern = "( [a-zA-Z0-9_]*=)";
          Regex regex = new Regex(pattern, RegexOptions.None);
    
    
          string[] result = regex.Split(text).
            Where(line => !regex.Match(line).Success).ToArray();
    
          foreach (string line in result)
          {
            Console.WriteLine(line);
          }
    
          // Result : 
    
          // 2010-07-21 16:36:18
          //FG100A3907507008
          //0101023010
          //event             
          //ipsec
          //error
          //192.158.33.17
          //4500            
          //200.221.90.436
          //40992
          //wan1
          //dialup_2            
          //97f81748ffb1b5af/7c6af4c338e9be44
          //dpd
          //dpd_failure            
          //'IPsec DPD detected a failure on the tunnel to 213.00.90.192:40992'
        }
      }
    }
    
    Regards,

    • Marked as answer by Alan_chen Monday, August 2, 2010 1:15 AM
    Wednesday, July 28, 2010 8:28 PM
  • String str =@"2010-07-21 16:36:18 device_id=FG100A3907507008 log_id=0101023010 type=event
    subtype=ipsec pri=error loc_ip=192.158.33.17 loc_port=4500
    rem_ip=200.221.90.436 rem_port=40992 out_if=wan1 vpn_tunnel=dialup_2
    cookies=97f81748ffb1b5af/7c6af4c338e9be44 action=dpd status=dpd_failure
    msg=""IPsec DPD detected a failure on the tunnel to 213.00.90.192:40992""";
    
    Regex rx = new Regex(@"\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d|(?<name>\w+)=(?<value>\w+)|(?<name>\w+)=""(?<value>[^""]*)""");
    
    foreach (Match m in rx.Matches(str))
    {
      string match = m.Value;
      string name = m.Groups["name"].Value;
      string value = m.Groups["value"].Value;
    
      if (name == "")
        Console.WriteLine(match);
      else
        Console.WriteLine("{0} = {1}", name, value);
    }
    
    Result:

    2010-07-21 16:36:18
    device_id = FG100A3907507008
    log_id = 0101023010
    type = event
    subtype = ipsec
    pri = error
    loc_ip = 192
    loc_port = 4500
    rem_ip = 200
    rem_port = 40992
    out_if = wan1
    vpn_tunnel = dialup_2
    cookies = 97f81748ffb1b5af
    action = dpd
    status = dpd_failure
    msg = IPsec DPD detected a failure on the tunnel to 213.00.90.192:40992

    • Marked as answer by Alan_chen Monday, August 2, 2010 1:15 AM
    Wednesday, July 28, 2010 8:34 PM

All replies

  • Hi!

    If you can rely on the format of the string you are looking for (e.g. you do know that every ip address will look like this: ###.###.###.###), you can use regular expressions. They're fast, efficient, and they can reduce the logic of selecting a certain substring from a larger string.

    Consult this page on this subject: http://msdn.microsoft.com/en-us/library/hs600312(VS.71).aspx

    If you cannot use RegEx for any reason, I'll try to help with solving a problem using string.split. :)

    Hope I could help!

    D.

    • Proposed as answer by David Fulop Wednesday, July 28, 2010 10:51 AM
    Wednesday, July 28, 2010 10:51 AM
  • Hi,

    The issue "but instead of the ipsec and192.158.33.17 i get subtype and rem_ip" was because of new line characters in the input value. PFB the modified code which extracts all the values after the = sign and writes to the text file. It also extracts the message.

     string Value = @"2010-07-21 16:36:18 device_id=FG100A3907507008 log_id=0101023010 type=event
    
                  subtype=ipsec pri=error loc_ip=192.158.33.17 loc_port=4500
    
                  rem_ip=200.221.90.436 rem_port=40992 out_if=wan1 vpn_tunnel=dialup_2
    
                  cookies=97f81748ffb1b5af/7c6af4c338e9be44 action=dpd status=dpd_failure
    
                  msg=IPsec DPD detected a failure on the tunnel to 213.00.90.192:40992";
          Value = Value.Replace(System.Environment.NewLine, " ");      
          string[] s1 = Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
          for (int i = 0; i <= 1; i++)
          {
            StreamWriter sw = File.AppendText("D:\\text4.txt");
            sw.WriteLine(s1[i]);
            sw.Close();
          }
    
          for (int i = 2; i < s1.Length; i++)
          {
            
            string[] s2 = s1[i].Split(new string[] { "=" }, StringSplitOptions.None);
            if(s2.Length == 1)
            {
              continue;
            }
            
            StreamWriter sw = File.AppendText("D:\\text4.txt");
            if (s2[0] == "msg")
            {
              StringBuilder Build = new StringBuilder();
              Build.Append(s2[1]);
              Build.Append(" ");
              for(int InnerIndex = i + 1; InnerIndex < s1.Length; InnerIndex++)
              {
                Build.Append(s1[InnerIndex]);
                Build.Append(" ");
              }
              sw.WriteLine(Build);
            }
            else
            {
              sw.WriteLine(s2[1]);
            }
            sw.Close();
    
          }
    

    [Please mark the post as answer if it answers your question]

    Thanks & Regards,

    Sai Pavan

    • Proposed as answer by Thuru VMVP Thursday, July 29, 2010 7:54 AM
    Wednesday, July 28, 2010 11:17 AM
  • actually the base approach would first use the common string.Split and split it by the whitespace if the '=' if there is no whitespace before or after it and in this case that is correct. But if so let make sure the '=' has no whitespace.

    line = Regex.Replace(" =", "=");

    line = Regex.Replace("= ", "=");

    string[] split = line.Split(' ');

    List<string> values;

    List<string> names;

    for (int i = 0; i < split.Length; i++)

    {

       split[i] = split[i].Trim(); //get rid of any left over whitespace from

       

    //now we have a trimmed array of only the name=value

    //for each of the strings in split

        string[] tSplit;

        tSplit = split[i].Split("=");

        if (tSplit[0] == "" || tSplit[1] == "")

           return exception;

        names.Add(tSplit[0]);

        values.Add(tSplit[1]);

    }

    }

    now you have the names and values which have the same corresponding index. And you can do what you need to do just remember to instantiate the names and values lists before entering the loop

     

    • Proposed as answer by bvrwoo_3376 Wednesday, July 28, 2010 3:07 PM
    Wednesday, July 28, 2010 3:05 PM
  • While that looks like it's getting along the right path, it still doesn't handle the case of the last line, which is that the value can contain spaces if contained in quotes, so if that needs to be handled there really isn't any choice but to use regular expressions.

    matching something along the lines of: (\s\S*=\S*\s)|(\s\S*=".*")
    Note that this would need to be run as a multiline regular expression.

    In english, that translates to: find a whitespace character followed by a series of non-whitespace characters followed by an equals sign followed by a series of non-whitespace characters and then a whitespace character, or find a whitespace character followed by a series of non-whitespace characters followed by an equals sign followed by a series of non-line break characters surrounded by quotes.

    Once you match that you'll probably need to remove some of the whitespace characters from your result (if someone has a regex that doesn't keep them it would be nice) and then split the string on the equals character.  You'll also need to remove the quotes from the value expression if it matches the second one.

    Wednesday, July 28, 2010 4:19 PM
  • bvrwoo_3376

    PLEASE STOP marking your won posts as proposed as answered!

    Wednesday, July 28, 2010 4:33 PM
  • Suppose you have a string as follows.

    String str = "2010-07-21 16:36:18 device_id=FG100A3907507008 log_id=0101023010 type=event

    subtype=ipsec pri=error loc_ip=192.158.33.17 loc_port=4500

    rem_ip=200.221.90.436 rem_port=40992 out_if=wan1 vpn_tunnel=dialup_2

    cookies=97f81748ffb1b5af/7c6af4c338e9be44 action=dpd status=dpd_failure

    msg="IPsec DPD detected a failure on the tunnel to 213.00.90.192:40992" 

     

    First you call str.Split("\n"), it will returns String Array. Then iterate to each line and call str.Split("=")

     


    Ovais
    Wednesday, July 28, 2010 6:33 PM
  • Hi,

    You can simply use Regex.Split :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.IO;
    
    namespace Test.SplitString
    {
      class Program
      {
        static void Main(string[] args)
        {
          string text = @"2010-07-21 16:36:18 device_id=FG100A3907507008 log_id=0101023010 type=event
                  subtype=ipsec pri=error loc_ip=192.158.33.17 loc_port=4500
                  rem_ip=200.221.90.436 rem_port=40992 out_if=wan1 vpn_tunnel=dialup_2
                  cookies=97f81748ffb1b5af/7c6af4c338e9be44 action=dpd status=dpd_failure
                  msg='IPsec DPD detected a failure on the tunnel to 213.00.90.192:40992'";
    
          string pattern = "( [a-zA-Z0-9_]*=)";
          Regex regex = new Regex(pattern, RegexOptions.None);
    
    
          string[] result = regex.Split(text).
            Where(line => !regex.Match(line).Success).ToArray();
    
          foreach (string line in result)
          {
            Console.WriteLine(line);
          }
    
          // Result : 
    
          // 2010-07-21 16:36:18
          //FG100A3907507008
          //0101023010
          //event             
          //ipsec
          //error
          //192.158.33.17
          //4500            
          //200.221.90.436
          //40992
          //wan1
          //dialup_2            
          //97f81748ffb1b5af/7c6af4c338e9be44
          //dpd
          //dpd_failure            
          //'IPsec DPD detected a failure on the tunnel to 213.00.90.192:40992'
        }
      }
    }
    
    Regards,

    • Marked as answer by Alan_chen Monday, August 2, 2010 1:15 AM
    Wednesday, July 28, 2010 8:28 PM
  • String str =@"2010-07-21 16:36:18 device_id=FG100A3907507008 log_id=0101023010 type=event
    subtype=ipsec pri=error loc_ip=192.158.33.17 loc_port=4500
    rem_ip=200.221.90.436 rem_port=40992 out_if=wan1 vpn_tunnel=dialup_2
    cookies=97f81748ffb1b5af/7c6af4c338e9be44 action=dpd status=dpd_failure
    msg=""IPsec DPD detected a failure on the tunnel to 213.00.90.192:40992""";
    
    Regex rx = new Regex(@"\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d|(?<name>\w+)=(?<value>\w+)|(?<name>\w+)=""(?<value>[^""]*)""");
    
    foreach (Match m in rx.Matches(str))
    {
      string match = m.Value;
      string name = m.Groups["name"].Value;
      string value = m.Groups["value"].Value;
    
      if (name == "")
        Console.WriteLine(match);
      else
        Console.WriteLine("{0} = {1}", name, value);
    }
    
    Result:

    2010-07-21 16:36:18
    device_id = FG100A3907507008
    log_id = 0101023010
    type = event
    subtype = ipsec
    pri = error
    loc_ip = 192
    loc_port = 4500
    rem_ip = 200
    rem_port = 40992
    out_if = wan1
    vpn_tunnel = dialup_2
    cookies = 97f81748ffb1b5af
    action = dpd
    status = dpd_failure
    msg = IPsec DPD detected a failure on the tunnel to 213.00.90.192:40992

    • Marked as answer by Alan_chen Monday, August 2, 2010 1:15 AM
    Wednesday, July 28, 2010 8:34 PM
  • Hi,

    you could refer the following code

     

     

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

     

    namespace SplitTest

    {

        class Program

        {       

            static void Main(string[] args)

            {

                string Value = @"2010-07-21 16:36:18 device_id=FG100A3907507008 log_id=0101023010 type=event

     

                  subtype=ipsec pri=error loc_ip=192.158.33.17 loc_port=4500

     

                  rem_ip=200.221.90.436 rem_port=40992 out_if=wan1 vpn_tunnel=dialup_2

     

                  cookies=97f81748ffb1b5af/7c6af4c338e9be44 action=dpd status=dpd_failure

     

                  msg=IPsec DPD detected a failure on the tunnel to 213.00.90.192:40992";

     

                string[] NewValue = Value.Split(new string[]{"="}, StringSplitOptions.None);

                for (int i = 0; i < NewValue.Length;i++ )

                {

                    Console.WriteLine("{0}", NewValue[i]);

                }

            }

        }

    }

     

    Thanks

    Larcolais Gong

    Thursday, July 29, 2010 7:36 AM