要添加到Observable Collection中的多个数据分析

时间:2015-07-17 17:37:39

标签: c# regex

我试图分解一串看起来像这样的信息

00:02:38: Message
00:02:39: Message
00:02:41: Message
...

使用正则表达式,所以我可以将它填充到一个可观察的集合中。我有以下代码,我可以每次解析每行和每行的消息

Regex timeMatch = new Regex("([0-9]{2}:[0-9]{2}:[0-9]{2})");
Regex msgMatch = new Regex("([A-Z])(.*)");

foreach (Match msgItem in msgMatch.Matches(logMessges)) {
    Debug.WriteLine(msgItem.Value);
}
foreach(Match timeItem in timeMatch.Matches(logMessges)) {
    Debug.WriteLine(timeItem.Value);
}

将以下内容输出到Debug输出中,这就是我想要的

00:02:38
00:02:39
00:02:41

Message
Message
Message

将这些值添加到我已使用以下类创建的新ObservableCollection中的最佳方法是什么

public class CallLog {
    public string Time { get; set; }
    public string Message { get; set; }
}

ObservableCollection<CallLog> log = new ObservableCollection<CallLog>();
log.Add(new CallLog {Time = timeItem.Value, Message = msgItem.Value};

使用以下方式获得奇怪的行为

Regex pattern = new Regex("([0-9]{2}:[0-9]{2}:[0-9]{2})|([A-Z].*)");
foreach (Match m in pattern.Matches(logMessges)) {
    log.Add(new CallLog { Time = m.Groups[1].Value, Message = m.Groups[2].Value });
}

Results:

Time         Message
--------------------
00:02:38
             Message
00:02:39
             Message
00:02:41
             Message

预期的行为是排队

Time        Message
-------------------
00:02:39    Message
....

3 个答案:

答案 0 :(得分:1)

Regex regex = new Regex("([0-9]{2}:[0-9]{2}:[0-9]{2}): ([A-Z].*)");
ObservableCollection<CallLog> log = new ObservableCollection<CallLog>();

foreach (Match match in regex.Matches(logMessges)) {
    log.Add(new CallLog {Time = match.Groups[1].Value, Message = match.Groups[2].Value});
}

正则表达式中常规括号之间的所有内容都会被捕获并作为一组存储在匹配中。因此,表达式[0-9]{2}:[0-9]{2}:[0-9]{2}匹配的任何内容都存储在第一组中,而[A-Z].*存储在第二组中。匹配正则表达式后,我们可以从Match.Groups中提取这些捕获。

答案 1 :(得分:1)

这里的派对有点晚了......但我只是通过使用命名的匹配Capture组将两个匹配的进程合二为一。

一旦获得了mathes(每行一个),就可以将它们( Linq代表Select )投射到CallLog实体中。从那里,每个人可以Aggregate成为可观察的集合。

  

数据设置

var text = @"00:02:38: Alpha Sentance
00:02:39: Beta
00:02:41: Omega";
  

模式捕获两组数据

var pattern = @"^(?<Time>[^\s]+)\s(?<Message>[^\r\n]+)";

以下代码返回ObservableCollection<CallLog>

Regex.Matches(text, pattern, RegexOptions.Multiline)
     .OfType<Match>()
     .Select (mt => new CallLog()
                    {
                        Time    = mt.Groups["Time"].Value,
                        Message = mt.Groups["Message"].Value
                    })
     .Aggregate(new ObservableCollection<CallLog>(),
                (collection, log) => { collection.Add(log); return collection;} )
  

结果

enter image description here

答案 2 :(得分:0)

使用Capture Collections进行此操作的方法 一次获取所有匹配 这要求所有消息按顺序排列。

虽然,我不知道这是否比步进更快(或不同) 通过找到下一个循环。

 # @"(?m)(?:^(?<TimeStamp>[0-9]{2}:[0-9]{2}:[0-9]{2}):\s+(?<Message>.*)\s*)+"

 (?m)
 (?:
      ^ 
      (?<TimeStamp>                 # (1 start)
           [0-9]{2} : 
           [0-9]{2} : 
           [0-9]{2} 
      )                             # (1 end)
      : \s+ 
      (?<Message> .* )              # (2)
      \s* 
 )+

C#:

string log = @"
00:02:38: Message1
00:02:39: Message2
00:02:41: Message3
";
Regex RxLog = new Regex(@"(?m)(?:^(?<TimeStamp>[0-9]{2}:[0-9]{2}:[0-9]{2}):\s+(?<Message>.*)\s*)+");

Match logMatch = RxLog.Match( log );
if ( logMatch.Success )
{
    CaptureCollection ccTS = logMatch.Groups["TimeStamp"].Captures;
    CaptureCollection ccMSG = logMatch.Groups["Message"].Captures;
    for (int i = 0; i < ccTS.Count; i++)
        Console.WriteLine("[{0}] = {1}  {2}", i, ccTS[i].Value, ccMSG[i].Value);
}

输出:

 [0] = 00:02:38  Message1
 [1] = 00:02:39  Message2
 [2] = 00:02:41  Message3