2017-10-22 3 views
1

Ich habe eine riesige Liste von Nachrichten, die wie folgt in einem rohen Text formatiert sind:C# - Wie passe ich einen Wert an, der das passende Muster in Regex enthalten könnte?

[Date(m/d/y)], [time(nn:nn AM/PM)] - [name] : [message], 

Beispiel:

9/15/17, 12:33 PM - Brian Bouman: Hey, 

Gibt es trotzdem all die Dinge zwischen den Klammern zu extrahieren, auch wenn die Nachricht und Name kann sie auch enthalten?

Them , sein : und -

+0

Sehr einfach, das Datum ist immer bis zum ersten ',', danach die Zeit - bis die '-', der Name ist bis zur letzten ':' und danach die Nachricht .. – AsfK

+0

Wenn Sie generieren möchten ein Regex Ich denke, dass Sie [Xeger] (https://code.google.com/p/xeger/) -HTH;) verwenden können. –

Antwort

0

Sollte ziemlich gerade vorwärts

^(?<date>.*), (?<time>.*) - (?<name>.*): (?<message>.*),$ 

Erklärung:

^(?<date>.*), entspricht das Datum, alles zwischen dem Anfang der Zeile und dem ersten Komma .

(?<time>.*) - die Zeit paßt, etwas zwischen dem Raum und dem Zeichen „-“

(?<name>.*): entspricht den Namen, alles, von wo aus wir zum nächsten sind „:“

(?<message>.*),$ bringt die Nachricht, alles von wo wir sind "," und das Ende der Datei/Zeile.

1

Ich denke, Ihr Muster statt [Date(m/d/y)], [time(nn:nn AM/PM)] - [name] : [message],[Date(m/d/y)], [time(nn:nn AM/PM)] - [name]: [message], sein sollte - keinen Raum nach [name] - also eine Art und Weise, ist dies:

// A dynamic pattern is given 
var pattern = @"[Date(m/d/y)], [time(nn:nn AM/PM)] - [name]: [message],";  

// in patternMaps; I make pattern conventions 
var patternMaps = new Dictionary<string, string> 
         { 
          { "[mdy]", @"\d\d?" }, // I will replace `m`,`d`,`y`s between parentheses to accept one or two digits 
          { "n", @"\d" },   // I will replace `n`s between parentheses to accept one digit only 
          { @"AM/PM", "(AM|PM)" }, // I will replace `AM/PM` between parentheses to accept `AM` or `PM` 
          { "[/]", @"\/" }   // I will replace `/` between parentheses to `\/` for removing regex exception 
         }; 

// `parts` contains name and patterns between brackets 
var parts = 
    Regex.Matches(pattern, @"\[(?<part>[^(\]]+)(\((?<pattern>[^)]+)\))?]") 
     .OfType<Match>() 
     .ToDictionary(
      k => k.Groups["part"].ToString(), 
      v => v.Groups["pattern"].ToString()); 

// Applying patternMaps to patterns 
parts = patternMaps.Aggregate(
    parts, 
    (current, pm) => current.ToDictionary(k => k.Key, v => Regex.Replace(v.Value, pm.Key, pm.Value))); 

// generate fit pattern for creating a proper regex 
var regexPattern = Regex.Replace(
    Regex.Replace(pattern, @"\([^)]+\)", string.Empty), 
    @"\[(?<part>[^]]+)\]", 
    c => 
     { 
      var part = parts.SingleOrDefault(p => p.Key == c.Groups["part"].ToString()); 
      return string.IsNullOrWhiteSpace(part.Value) ? [email protected]"(?<{part.Key}>[\w ]+)" : [email protected]"(?<{part.Key}>{part.Value})"; 
     }); 

var message = "9/15/17, 12:33 PM - Brian Bouman: Hey,"; 

// Applying generated pattern to message 
var result = Regex.Match(message, $"^{regexPattern}$"); // "^...$" means whole - from the beginning to the end pf - the string 

if (result.Success) 
{ 
    Console.WriteLine($"## Message matched##: {message}"); 

    foreach (var part in parts) 
    { 
     Console.WriteLine($"{part.Key}: {result.Groups[$"{part.Key}"]}"); 
    } 
} 
else 
{ 
    Console.WriteLine($"Message not matched!: {message}"); 
} 

C# Fiddle Demo

Eigentlich ich zuerst einen regulären Ausdruck aus einem bestimmten Muster erzeugen dann wende ich es über eine Nachricht an, um jeden Teil -HTH zu sammeln;).

Verwandte Themen