Was ist der beste Weg, dies in C ++ zu analysieren?

8

In meinem Programm habe ich eine Liste von "Serveradresse" im folgenden Format:

%Vor%

Die Klammern hier zeigen an, dass port optional ist.

  • host kann ein Hostname, eine IPv4- oder IPv6-Adresse sein (möglicherweise in der "Klammer-eingeschlossenen" Notation).
  • port , falls vorhanden, kann eine numerische Portnummer oder eine Servicezeichenfolge sein (wie: "http" oder "ssh").

Wenn port vorhanden ist und host eine IPv6-Adresse ist, muss host in der "Klammer eingeschlossen" -Notation sein (Beispiel: [::1] )

Hier sind einige gültige Beispiele:

%Vor%

Und ein ungültiges Beispiel:

%Vor%

Mein Ziel ist es, solche Einträge in zwei Teile zu trennen (offensichtlich host und port ). Es ist mir egal, ob entweder host oder port ungültig sind, solange sie kein nicht-eckiges : enthalten ( 290.234.34.34.5 ist ok für host , wird in abgelehnt.) der nächste Prozess); Ich möchte nur die beiden Teile trennen, oder wenn es kein port part gibt, weiß es irgendwie.

Ich habe versucht, etwas mit std::stringstream zu tun, aber alles, was ich vorhabe, scheint hacky und nicht wirklich elegant.

Wie würden Sie das in C++ machen?

Ich habe keine Probleme mit Antworten in C , aber C++ wird bevorzugt. Jede boost Lösung ist ebenfalls willkommen.

Danke.

    
ereOn 02.06.2010, 14:40
quelle

5 Antworten

9

Habt ihr boost :: Geist ? Es könnte jedoch für Ihre Aufgabe übertrieben sein.

    
sbi 02.06.2010, 14:47
quelle
5

Hier ist eine einfache Klasse, die boost :: xpressive verwendet, um den Typ der IP-Adresse zu überprüfen und dann den Rest zu parsen, um die Ergebnisse zu erhalten.

Verwendung:

%Vor%

Die Header-Datei der Klasse, IpAddress.h

%Vor%

Die Quelldatei für die Klasse, IpAddress.cpp

%Vor%

Ich habe nur die Regeln für IPv4 festgelegt, weil ich das richtige Format für IPv6 nicht kenne. Aber ich bin mir ziemlich sicher, dass es nicht schwer ist, es zu implementieren. Boost Xpressive ist nur eine vorlagenbasierte Lösung und erfordert daher keine .lib-Dateien, die in Ihre exe kompiliert werden müssen, was meines Erachtens ein Plus ist.

Übrigens, um das Format von Regex auf den Punkt zu bringen ...
^ = Beginn der Zeichenkette
$ = Ende der Zeichenkette
[] = eine Gruppe von Buchstaben oder Ziffern, die angezeigt werden kann [0-9] = jede einzelne Ziffer zwischen 0 und 9
< stark> [0-9] + = eine oder mehrere Ziffern zwischen 0 und 9
das '.' hat eine besondere Bedeutung für Regex, aber da unser Format 1 Punkt in einem IP-Adressformat hat, müssen wir angeben, dass wir ein '.' zwischen den Ziffern mit '\.' Aber da C ++ eine Escape-Sequenz für '\' benötigt, müssen wir "\\." Verwenden. ? = optionale Komponente

Kurz gesagt, "^ [0-9] + $" ist eine Regex, was für eine ganze Zahl gilt.
"^ [0-9] + \. $ " bedeutet eine Ganzzahl, die mit einem '.' endet.
" ^ [0-9] + \. [0-9]? $ " ist entweder eine Ganzzahl das endet mit einem "." oder eine Dezimalzahl.
Für eine ganze Zahl oder eine reelle Zahl wäre die Regex "^ [0-9] + (\. [0-9] *)? $" .
RegEx eine Ganzzahl zwischen 2 und 3 Zahlen ist "^ [0-9] {2,3} $" .

Jetzt um das Format der IP-Adresse zu brechen:

%Vor%

Dies ist gleichbedeutend mit: "^ [0-9] {1,3} \. [0-9] {1,3} \. [0-9] {1,3} \. [0-9 ] + (\: [0-9] {1,5})? $ ", Was bedeutet:

%Vor%

Die zweite RegEx ist einfacher als das. Es ist nur eine Kombination aus einem alphanumerischen Wert gefolgt von einem optionalen Doppelpunkt und einer Portnummer Übrigens, wenn Sie RegEx testen möchten, können Sie diese Site verwenden.

Bearbeiten : Ich habe nicht bemerkt, dass Sie optional http anstelle der Portnummer hatten. Dafür können Sie den Ausdruck folgendermaßen ändern:

%Vor%

Dies akzeptiert Formate wie:
127.0.0.1
127.0.0.1:3282
127.0.0.1:http
217.0.0.1:ftp
18.123.2.1:smtp

    
Vite Falcon 02.06.2010 16:16
quelle
3
%Vor%     
Billy ONeal 02.06.2010 18:21
quelle
0

Wie bereits erwähnt, könnte Boost.Spirit.Qi damit umgehen.

Wie bereits erwähnt, ist es (wirklich) übertrieben.

%Vor%

Ich glaube wirklich nicht, dass dies eine Parsing-Bibliothek rechtfertigt, es könnte wegen der überladenen Verwendung von : nicht an Lesbarkeit gewinnen.

Nun ist meine Lösung sicherlich nicht fehlerlos, man könnte sich zum Beispiel über seine Effizienz wundern ... aber ich denke wirklich, dass es ausreicht, und zumindest werden Sie den nächsten Betreuer nicht verlieren, denn aus Erfahrung können Qi-Ausdrücke alles andere als sein klar!

    
Matthieu M. 02.06.2010 15:54
quelle
-3

Wenn Sie den Port und Host über eine Zeichenfolge oder in C ++ ein Array von Zeichen erhalten; Sie könnten die Länge der Zeichenfolge erhalten. Führen Sie eine for-Schleife bis zum Ende der Zeichenfolge aus und gehen Sie so lange, bis Sie einen einzelnen Doppelpunkt selbst gefunden haben und die Zeichenfolge an dieser Stelle in zwei Teile aufteilt.

%Vor%

Nur ein Vorschlag ist ein bisschen tief und ich bin mir sicher, dass es einen effizienteren Weg gibt, aber hoffe das hilft, Sturm

    
geshafer 02.06.2010 14:55
quelle

Tags und Links