Fehler "Unbekannte Escape-Sequenz" in Go

71

Ich habe die folgende Funktion in Go geschrieben. Die Idee ist, dass der Funktion eine Zeichenfolge übergeben wird und die erste gefundene IPv4-IP-Adresse zurückgegeben wird. Wird keine IP-Adresse gefunden, wird eine leere Zeichenfolge zurückgegeben.

func parseIp(checkIpBody string) string {
    reg, err := regexp.Compile("[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
    if err == nil {
        return ""
    }   
    return reg.FindString(checkIpBody)
}

Der Fehler beim Kompilieren ist

unbekannte Fluchtfolge :.

Wie kann ich Go sagen, dass dies '.'der eigentliche Charakter ist, den ich suche? Ich dachte, es würde den Trick machen, aber anscheinend irre ich mich.

Nate
quelle
Es ist eine alte Frage, aber jeden Tag haben Menschen Probleme mit Regexen. Eine sehr, sehr nützliche Sache, wenn Sie mit regulären Ausdrücken arbeiten (unabhängig von der verwendeten Sprache), ist das Drucken von regulären Ausdrücken, um zu überprüfen, ob es wirklich das ist, was Sie denken.
Artur
Diese Frage ist auch relevant für Prometheus (Promql Regex)
Alec Istomin

Antworten:

142

Der \Backslash wird nicht vom Regex-Parser interpretiert, sondern im String-Literal. Sie sollten dem Backslash erneut entkommen:

regexp.Compile("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+")

Eine Zeichenfolge mit "doppelten Anführungszeichen wird in Go als " interpretiertes Zeichenfolgenliteral" bezeichnet. Interpretierte String-Literale sind in den meisten Sprachen wie String-Literale: \Backslash-Zeichen sind nicht wörtlich enthalten, sondern werden verwendet, um dem nächsten Zeichen eine besondere Bedeutung zu geben. Die Quelle muss \\zwei Backslashes hintereinander enthalten, um ein einzelnes Backslash-Zeichen im analysierten Wert zu erhalten.

Go hat eine andere Alternative, die beim Schreiben von String-Literalen für reguläre Ausdrücke nützlich sein kann: Ein " Raw- String-Literal" wird durch `Backtick-Zeichen zitiert . Es gibt keine Sonderzeichen in einem rohen String-Literal. Solange Ihr Muster keinen Backtick enthält, können Sie diese Syntax verwenden, ohne sich irgendetwas zu entziehen:

regexp.Compile(`[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+`)

Diese werden im Abschnitt "String-Literale" der Go-Spezifikation beschrieben .

Jeremy
quelle
Das hat mich wahnsinnig gemacht! Vielen Dank!
Andrew Horn
1

IPv4-Adresse (genaue Erfassung)

Entspricht 0.0.0.0 bis 255.255.255.255

Verwenden Sie diesen regulären Ausdruck, um IP-Nummern genau abzugleichen.

Jede der 4 Nummern wird in einer Erfassungsgruppe gespeichert, sodass Sie zur weiteren Verarbeitung darauf zugreifen können.

"(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])"
Montag
quelle
Schöne gründliche Regex. Vielen Dank.
Nate
1
Angesichts der Komplexität des regulären Ausdrucks würde ich wahrscheinlich die Zeichenfolge in Ganzzahlen konvertieren und stattdessen auf diese Weise überprüfen. In einem Jahr bezweifle ich, dass ich mich sehr gut an die Details dieses Ausdrucks erinnern würde. Diese Art von Code hat mich schon einmal gebissen. Go-Bibliotheken unterstützen möglicherweise sogar diese Art der Überprüfung ... Im Moment vertraue ich nur darauf, dass die vom Server gesendete Zeichenfolge korrekt ist, solange sie 4 Bytes durch Punkte (".") Getrennt ist.
Nate
Um das Lesen zu erleichtern, mache ich normalerweise: numBlock="(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])" regexPattern=numBlock + "\\." + numBlock + "\\." + numBlock + "\\." + numBlock
Nashenas