【问题标题】:Split String by space with limited splitting C#用有限的分割C#按空间分割字符串
【发布时间】:2014-11-11 06:54:46
【问题描述】:

示例输入

1   0.000000 10.19.20.105 -> 74.125.236.200 ICMP 74 Echo (ping) request  id=0x000a, seq=51187/62407, ttl=128
6   0.097977 74.125.236.194 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62844/31989, ttl=57 (request in 2)
7   0.131456 74.125.236.198 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62845/32245, ttl=57 (request in 3)
8   0.143539 74.125.236.196 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62847/32757, ttl=57 (request in 5)
9   0.160567 74.125.236.192 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62846/32501, ttl=57 (request in 4)
10   0.177972 10.19.20.172 -> 10.19.20.255 NBNS 92 Name query NB INDERPAL-PC<1c>
11   0.270418 10.19.20.105 -> 74.125.236.194 ICMP 74 Echo (ping) request  id=0x000b, seq=62848/33013, ttl=128
12   0.318404 10.19.20.105 -> 74.125.236.194 ICMP 74 Echo (ping) request  id=0x000b, seq=62849/33269, ttl=128
13   0.330236 74.125.236.194 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62848/33013, ttl=57 (request in 11)
14   0.376039 74.125.236.194 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62849/33269, ttl=57 (request in 12)
17   0.397384 10.19.20.105 -> 74.125.236.195 ICMP 74 Echo (ping) request  id=0x000b, seq=62852/34037, ttl=128
18   0.438108 74.125.236.200 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62850/33525, ttl=57 (request in 15)
19   0.444489 10.19.20.105 -> 74.125.236.196 ICMP 74 Echo (ping) request  id=0x000b, seq=62853/34293, ttl=128
21   0.463515 74.125.236.195 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62852/34037, ttl=57 (request in 17)
22   0.475425 10.19.20.105 -> 74.125.236.197 ICMP 74 Echo (ping) request  id=0x000b, seq=62854/34549, ttl=128
25   0.522472 74.125.236.197 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62854/34549, ttl=57 (request in 22)
26   0.535794 Giga-Byt_5d:06:ac -> Broadcast    ARP 60 Who has 10.19.20.74?  Tell 10.19.20.94
27   0.537735 Giga-Byt_a0:ad:23 -> Broadcast    ARP 60 Who has 10.19.20.94?  Tell 10.19.20.74
28   0.550321 10.19.20.105 -> 74.125.200.95 TCP 55 58240→80 [ACK] Seq=1 Ack=1 Win=16402 Len=1
29   0.574957 JetwayIn_a0:b1:a2 -> Broadcast    ARP 60 Who has 10.19.20.180?  Tell 10.19.20.172
30   0.584448 74.125.236.195 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62855/34805, ttl=57 (request in 24)


public class DataGridClass
    {
        public int SerialNumber { get; set; }
        public string Time { get; set; }
        public string DestinationIP { get; set; }
        public string SourceIP { get; set; }
        public string Protocol { get; set; }
        public int Length { get; set; }
        public string Info { get; set; }
    }

期望的输出

SerialNumber = 1
Time = "0.000000"
DestinationIP = "10.19.20.105"
SourceIP = "74.125.236.200"
Protocol = "ICMP"
Length = 74
Info = "Echo (ping) request  id=0x000a, seq=51187/62407, ttl=128"

我无法用空格分割,因为字符串不一致,其次空格的数量可能会增加或减少

提前致谢

更新:

26、27和别人不一样

【问题讨论】:

  • 你只给了我们一个例子——我们要如何解决它可能不一致的地方?限制执行的拆分次数很容易,但我们不知道您所说的不一致是什么意思...
  • 使用test.Split(new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries),将前7个子字符串(跳过“->”)分配到类中,将其余部分放入Info
  • 除非您正在练习拆分/正则表达式,否则已经有 Ping 类。
  • /(\d+)\s+([\d\.]+)\s+([\d.]+)[\s->]+([\d\.]+) \s+([a-zA-Z]+)\s+([\d]+)\s+(.+) - 试试这个。
  • @AlexeiLevenkov 是的,我知道 Ping 类,但是如何在不丢失信息的情况下将这些数据解析到该类?

标签: c# regex split


【解决方案1】:

您可以只使用正则表达式。这似乎适用于您的数据。
注意 - 如果 Dot-net 支持它,请使用水平制表符 \h+ 代替下面的所有 \s+

 #  @"(?m)^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)"

 (?m)
 ^ 
 ( \S+ )            # (1), Serial Number
 \s+ 
 ( \S+ )            # (2), Time
 \s+ 
 ( \S+ )            # (3), Destination IP
 \s+ 
 ( \S+ )            # (4), ->
 \s+ 
 ( \S+ )            # (5), Source IP
 \s+ 
 ( \S+ )            # (6), Protocol
 \s+ 
 ( \S+ )            # (7), Length
 \s+ 
 ( .* )             # (8), Info

第 1、26、27 行的输出样本

 **  Grp 0 -  ( pos 0 , len 108 ) 
1   0.000000 10.19.20.105 -> 74.125.236.200 ICMP 74 Echo (ping) request  id=0x000a, seq=51187/62407, ttl=128  
 **  Grp 1 -  ( pos 0 , len 1 ) 
1  
 **  Grp 2 -  ( pos 4 , len 8 ) 
0.000000  
 **  Grp 3 -  ( pos 13 , len 12 ) 
10.19.20.105  
 **  Grp 4 -  ( pos 26 , len 2 ) 
->  
 **  Grp 5 -  ( pos 29 , len 14 ) 
74.125.236.200  
 **  Grp 6 -  ( pos 44 , len 4 ) 
ICMP  
 **  Grp 7 -  ( pos 49 , len 2 ) 
74  
 **  Grp 8 -  ( pos 52 , len 56 ) 
Echo (ping) request  id=0x000a, seq=51187/62407, ttl=128  

--------------------------------

 **  Grp 0 -  ( pos 1873 , len 93 ) 
26   0.535794 Giga-Byt_5d:06:ac -> Broadcast    ARP 60 Who has 10.19.20.74?  Tell 10.19.20.94  
 **  Grp 1 -  ( pos 1873 , len 2 ) 
26  
 **  Grp 2 -  ( pos 1878 , len 8 ) 
0.535794  
 **  Grp 3 -  ( pos 1887 , len 17 ) 
Giga-Byt_5d:06:ac  
 **  Grp 4 -  ( pos 1905 , len 2 ) 
->  
 **  Grp 5 -  ( pos 1908 , len 9 ) 
Broadcast  
 **  Grp 6 -  ( pos 1921 , len 3 ) 
ARP  
 **  Grp 7 -  ( pos 1925 , len 2 ) 
60  
 **  Grp 8 -  ( pos 1928 , len 38 ) 
Who has 10.19.20.74?  Tell 10.19.20.94  

----------------------------

 **  Grp 0 -  ( pos 1968 , len 93 ) 
27   0.537735 Giga-Byt_a0:ad:23 -> Broadcast    ARP 60 Who has 10.19.20.94?  Tell 10.19.20.74  
 **  Grp 1 -  ( pos 1968 , len 2 ) 
27  
 **  Grp 2 -  ( pos 1973 , len 8 ) 
0.537735  
 **  Grp 3 -  ( pos 1982 , len 17 ) 
Giga-Byt_a0:ad:23  
 **  Grp 4 -  ( pos 2000 , len 2 ) 
->  
 **  Grp 5 -  ( pos 2003 , len 9 ) 
Broadcast  
 **  Grp 6 -  ( pos 2016 , len 3 ) 
ARP  
 **  Grp 7 -  ( pos 2020 , len 2 ) 
60  
 **  Grp 8 -  ( pos 2023 , len 38 ) 
Who has 10.19.20.94?  Tell 10.19.20.74  

【讨论】:

    【解决方案2】:

    试试这个:

    (^\d*) SerialNumber = 1
    (\s\d*[.]\d*\s) Time = "0.000000"
    
    \b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b - [0] - first IP, [1] - second IP 
    
    DestinationIP = "10.19.20.105"
    SourceIP = "74.125.236.200"
    
    ([A-Z]{2,}) Protocol = "ICMP"
    (\s\d{1,}\s) Length = 74
    ((Echo).*) Info = "Echo (ping) request  id=0x000a, seq=51187/62407, ttl=128"
    

    【讨论】:

      【解决方案3】:

      要解决空格不一致的问题,请使用:

      var items = test.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries);
      

      幸运的是,您的所有数据都按照一致的顺序排列,并且数据中不包含随机空格。因此,鉴于上述拆分所采用的项目,您应该会发现以下始终正确分配:

      var dataGrid = new DataGridClass();
      
      dataGrid.SerialNumber = int.Parse(items[0]);
      dataGrid.Time = items[1];
      dataGrid.SourceIP = items[2];
      dataGrid.DestinationIP = items[4]; // Not a typo, we have to skip the ->
      dataGrid.Protocol = items[5];
      dataGrid.Length = int.Parse(items[6]);
      datagrid.Info = string.Join(" ", items.Skip(7));
      

      我试图巧妙地使用 Info,但如果它不像我想的那样工作,请随意简单地说:

      for (int i = 7; i < items.Length; ++i)
      {
          dataGrid.Info += items[i] + " ";
      }
      

      【讨论】:

      • 嗨,感谢您的回答,我已经更新了不一致数据的输入
      • 啊,还不错!看起来它们至少总是处于相同的顺序。当我到达办公室时,我会编辑我的答案:)
      • 嗨,史蒂夫,我认为这会起作用,但是这是最好的方法,其次是在这个 l;ine var items = test.Split(' ', StringSplitOptions.RemoveEmptyEntries); 上得到一个无效的参数错误
      • 是的,现在可以使用,但这是最好的方法还是使用正则表达式更好因为我不擅长正则表达式?
      • 我也不擅长正则表达式。我想说根据您目前的要求,我的解决方案可能会更高效且更易于阅读。与所有代码一样,当我遇到当前解决方案的问题(例如速度或不正确的解析)时,我只会切换到我不太了解或不太容易访问的东西。
      【解决方案4】:

      我也会使用正则表达式

      ^(\d+)\s+(\S+)\s+(\S+)\s*->\s*(\S+)\s+(\S+)\s+(\d+)(.*)$

      开始(序列号)一个或多个空格(时间)一个或多个空格(目标IP)零个或多个空格->零个或多个空格(源IP)一个或多个空格(协议)一个一个或多个空格(长度)一个或多个空格(信息)结束

      class Program
      {
          static void Main(string[] args)
          {
              string []inputs = {@"1   0.000000 10.19.20.105 -> 74.125.236.200 ICMP 74 Echo (ping) request  id=0x000a, seq=51187/62407, ttl=128",
                                  @"6   0.097977 74.125.236.194 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62844/31989, ttl=57 (request in 2)",
                                  @"7   0.131456 74.125.236.198 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62845/32245, ttl=57 (request in 3)",
                                  @"8   0.143539 74.125.236.196 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62847/32757, ttl=57 (request in 5)",
                                  @"9   0.160567 74.125.236.192 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62846/32501, ttl=57 (request in 4)",
                                  @"10   0.177972 10.19.20.172 -> 10.19.20.255 NBNS 92 Name query NB INDERPAL-PC<1c>",
                                  @"11   0.270418 10.19.20.105 -> 74.125.236.194 ICMP 74 Echo (ping) request  id=0x000b, seq=62848/33013, ttl=128",
                                  @"12   0.318404 10.19.20.105 -> 74.125.236.194 ICMP 74 Echo (ping) request  id=0x000b, seq=62849/33269, ttl=128",
                                  @"13   0.330236 74.125.236.194 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62848/33013, ttl=57 (request in 11)",
                                  @"14   0.376039 74.125.236.194 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62849/33269, ttl=57 (request in 12)",
                                  @"17   0.397384 10.19.20.105 -> 74.125.236.195 ICMP 74 Echo (ping) request  id=0x000b, seq=62852/34037, ttl=128",
                                  @"18   0.438108 74.125.236.200 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62850/33525, ttl=57 (request in 15)",
                                  @"19   0.444489 10.19.20.105 -> 74.125.236.196 ICMP 74 Echo (ping) request  id=0x000b, seq=62853/34293, ttl=128",
                                  @"21   0.463515 74.125.236.195 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62852/34037, ttl=57 (request in 17)",
                                  @"22   0.475425 10.19.20.105 -> 74.125.236.197 ICMP 74 Echo (ping) request  id=0x000b, seq=62854/34549, ttl=128",
                                  @"25   0.522472 74.125.236.197 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62854/34549, ttl=57 (request in 22)",
                                  @"26   0.535794 Giga-Byt_5d:06:ac -> Broadcast    ARP 60 Who has 10.19.20.74?  Tell 10.19.20.94",
                                  @"27   0.537735 Giga-Byt_a0:ad:23 -> Broadcast    ARP 60 Who has 10.19.20.94?  Tell 10.19.20.74",
                                  @"28   0.550321 10.19.20.105 -> 74.125.200.95 TCP 55 58240→80 [ACK] Seq=1 Ack=1 Win=16402 Len=1",
                                  @"29   0.574957 JetwayIn_a0:b1:a2 -> Broadcast    ARP 60 Who has 10.19.20.180?  Tell 10.19.20.172",
                                  @"30   0.584448 74.125.236.195 -> 10.19.20.105 ICMP 74 Echo (ping) reply    id=0x000b, seq=62855/34805, ttl=57 (request in 24)",
                              };
      
              List<DataGridClass> data = new List<DataGridClass>();
              Match match;
              foreach (var item in inputs)
              {
                  match = Regex.Match(item, @"^(\d+)\s+(\S+)\s+(\S+)\s*->\s*(\S+)\s+(\S+)\s+(\d+)(.*)$");
                  if (match.Success )
                  {
                      data.Add(new DataGridClass { 
                          SerialNumber = Convert.ToInt32(match.Groups[1].Value),
                          Time = match.Groups[2].Value,
                          DestinationIP = match.Groups[3].Value,
                          SourceIP = match.Groups[4].Value,
                          Protocol = match.Groups[5].Value,
                          Length = Convert.ToInt32(match.Groups[6].Value),
                          Info = match.Groups[7].Value,
                      });
                  }
              }
      
              if (data.Count > 0)
              {
                  foreach (var item in data)
                  {
                      Console.WriteLine(String.Format("SN: {0}, T: {1}, DIP: {2}, SIP: {3}, P: {4}, L: {5}, I: {6}",
                          item.SerialNumber, item.Time, item.DestinationIP, item.SourceIP, item.Protocol, item.Length, item.Info));
                  }
              }
              Console.ReadLine();
          }
      }
      
      public class DataGridClass
      {
          public int SerialNumber { get; set; }
          public string Time { get; set; }
          public string DestinationIP { get; set; }
          public string SourceIP { get; set; }
          public string Protocol { get; set; }
          public int Length { get; set; }
          public string Info { get; set; }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-10-11
        • 2010-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多