2015-09-03 10 views
11

Auf den ersten Blick zugeben ich, dass diese Frage wie ein Duplikat dieser Frage sieht und alle anderen im Zusammenhang mit es:Regulärer Ausdruck, der alle gültigen Format entspricht IPv6-Adressen

Regular expression that matches valid IPv6 addresses

diese Frage in der Tat hat eine Antwort, die fast meine Frage beantwortet, aber nicht vollständig.

Der Code von dieser Frage, die ich habe Probleme mit, doch hatte den größten Erfolg mit, ist wie folgt:

private string RemoveIPv6(string sInput) 
{ 
    string pattern = @"(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))"; 
    //That is one looooong regex! From: https://stackoverflow.com/a/17871737/3472690 
    //if (IsCompressedIPv6(sInput)) 
     // sInput = UncompressIPv6(sInput); 
    string output = Regex.Replace(sInput, pattern, ""); 
    if (output.Contains("Addresses")) 
     output = output.Substring(0, "Addresses: ".Length); 

    return output; 
} 

Die Fragen, die ich mit dem RegexMuster hatte, wie in dieser Antwort zur Verfügung gestellt, David M. Syzdek's Answer , ist, dass es nicht passt und die vollständige Form der IPv6-Adressen, die ich darauf geworfen habe, entfernt.

Ich verwende das Regex-Muster, um IPv6-Adressen in Strings hauptsächlich durch Leerzeichen oder Nullwerte zu ersetzen.

Zum Beispiel

Addresses: 2404:6800:4003:c02::8a 

Neben ...

Addresses: 2404:6800:4003:804::200e 

Und schließlich ...

Addresses: 2001:4998:c:a06::2:4008 

entweder Alle werden nicht vollständig durch die regex abgestimmt oder nicht vollständig übereinstimmen.

Die Regex wird mir die restlichen Teile der Zeichenfolge zurück, wie unten dargestellt:

Addresses: 8a 

    Addresses: 200e 

    Addresses: 2:4008 

Wie man sehen kann, hat es sich Reste der IPv6-Adressen übrig, die zu erkennen ist schwer und entfernen aufgrund die unterschiedlichen Formate, die die Überreste annehmen. Unten ist die RegexMuster selbst für eine bessere Analyse:

(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])) 

Daher ist meine Frage, wie diese RegexMuster korrigiert werden kann, so kann sie übereinstimmen, und daher ist die vollständige Entfernung aller IPv6-Adressen ermöglichen, von eine Zeichenfolge, die nicht nur die IPv6-Adresse (n) selbst enthält?

Alternativ, wie kann das oben bereitgestellte Code-Snippet korrigiert werden, um das gewünschte Ergebnis zu liefern?

Für diejenigen, die sich wundern, bekomme ich die Zeichenfolge aus dem StandardOutput von nslookup Befehle, und die IPv6-Adressen werden immer unterschiedlich sein. Für die obigen Beispiele habe ich diese IPv6-Adressen von "google.com" und "yahoo.com" erhalten.

Ich bin nicht mit der eingebauten Funktion DNS-Einträge für einen guten Grund zu lösen, die ich nicht glaube, im Moment egal wird, also sind nslookup verwende.

Wie für den Code, der diese Funktion aufruft, falls erforderlich, ist wie folgt: (es selbst ist auch eine andere Funktion/Methode oder vielmehr Teil eines)

string output = ""; 
string garbagecan = ""; 
string tempRead = ""; 
string lastRead = ""; 
using (StreamReader reader = nslookup.StandardOutput) 
{ 
    while (reader.Peek() != -1) 
    { 
     if (LinesRead > 3) 
     { 
      tempRead = reader.ReadLine(); 
      tempRead = RemoveIPv6(tempRead); 

      if (tempRead.Contains("Addresses")) 
       output += tempRead; 
      else if (lastRead.Contains("Addresses")) 
       output += tempRead.Trim() + Environment.NewLine; 
      else 
       output += tempRead + Environment.NewLine; 
      lastRead = tempRead; 
     } 
     else 
      garbagecan = reader.ReadLine(); 
     LinesRead++; 
    } 
} 
return output; 

Die korrigierte regex sollte nur das Entfernen von IPv6-Adressen erlauben und IPv4-Adressen unberührt lassen. Die Zeichenfolge, die an die Regex übergeben wird, enthält nicht nur die IPv6-Adresse (n) und enthält fast immer weitere Details. Daher ist es unvorhersehbar, bei welchem ​​Index die Adressen angezeigt werden. Die Regex überspringt auch alle anderen IPv6-Adressen nach den ersten auftretenden IPv6-Adressen auch aus irgendeinem Grund, sollte es beachtet werden.

Entschuldigung, wenn es irgendwelche fehlenden Details gibt, werde ich mein Bestes versuchen, sie einzuschließen, wenn sie alarmiert werden. Ich würde auch lieber Code-Beispiele bearbeiten, wenn möglich, da ich fast kein Wissen über Regex habe.

+0

@nhahtdh Sie die Frage nicht gelesen habe, denke ich. Dies basiert auf dieser Antwort, ich benutze es bereits, aber festgestellt, dass es eine ganze Reihe von Fehlern hat (mehr Infos in der Frage hier). Sie können das oben angegebene Regex-Muster in der Tat mit demjenigen in dieser Antwort überprüfen; Sie sind gleich. vks hat bereits eine bessere Alternative zur Verfügung gestellt, die besser funktioniert als die, die jedoch keines der Probleme hat, die ich dabei erlebt habe. – Kaitlyn

+0

@nhahtdh Sie können auch die Regex aus dieser Antwort und diese Frage unter https://regex101.com/r/zI1mQ6/1 mit der von vks bereitgestellten Frage unter https://regex101.com/r/cT0hV4 vergleichen/5. – Kaitlyn

+1

Ah, es tut mir leid. Ich dachte, dass die Antwort von vks nicht das lokale Link-Format '%' enthält, aber es basiert tatsächlich auf dieser Antwort. Kommentar zurückgezogen – nhahtdh

Antwort

8
(?:^|(?<=\s))(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(?=\s|$) 

lookarounds Verwenden Sie können eine vollständige Übereinstimmung erzwingen, anstatt eine partial match.See Demo.

https://regex101.com/r/cT0hV4/5

+0

Vielen Dank, es funktioniert perfekt mit IPv6-Adressen, die von nslookup für "yahoo.com", "google.com", sowie "abc.xyz" zurückgegeben werden (Die wenigen, die ich kenne, werden sowohl IPv6- als auch IPv4-Adressen zurückgeben)). :) – Kaitlyn

+0

Könnten Sie bitte in der verknüpften Frage antworten, damit dies als Duplikat geschlossen werden kann? Oder vielleicht nach Merge fragen? –

+1

@AlexeiLevenkov das ist eigentlich kein duplicate.Guess sollten wir es lassen wie es ist :) – vks