2012-11-11 19 views
6

Ich versuche, den Anfang einer benannten einfangenden Gruppen in einer Zeichenfolge zu finden, um einen einfachen Parser zu erstellen (siehe related question). Dazu merkt sich die Funktion extract die letzte für Zeichen in der Variablen last4. Wenn die letzten 4 Zeichen gleich „(P <?“ Es der Beginn einer Erfassungsgruppe ist:Vergleichen von Zeichenfolgen in Go

package main 

import "fmt" 

const sample string = `/(?P<country>m((a|b).+)(x|y)n)/(?P<city>.+)` 

func main() { 
    extract(sample) 
} 

func extract(regex string) { 
    last4 := new([4]int32) 
    for _, c := range regex { 
     last4[0], last4[1], last4[2], last4[3] = last4[1], last4[2], last4[3], c 
     last4String := fmt.Sprintf("%c%c%c%c\n", last4[0], last4[1], last4[2], last4[3]) 
     if last4String == "(?P<" { 
      fmt.Print("start of capturing group") 
     } 
    } 
} 

http://play.golang.org/p/pqA-wCuvux

Aber dieser Code druckt nichts last4String == "(?P<" ist nie wahr, obwohl dies substrin erscheint in der Ausgabe, wenn ich last4String innerhalb der Schleife drucken. Wie Strings in Go dann vergleichen?

Und ist es eine elegantere Möglichkeit, einen int32 Array in einen String als fmt.Sprintf("%c%c%c%c\n", last4[0], last4[1], last4[2], last4[3])?

zu konvertieren

Alles andere könnte besser sein? Mein Code sieht für mich etwas unelegant aus.

Antwort

3

Wenn es nicht zur Selbsterziehung oder ähnlichem ist, möchten Sie wahrscheinlich das vorhandene RE parser in der Standardbibliothek verwenden und dann den AST "gehen", um zu tun, was auch immer erforderlich ist.

func Parse(s string, flags Flags) (*Regexp, error) 

Parse parst ein regulärer Ausdruck String s, durch die angegebenen Flags gesteuert, und gibt einen regulären Ausdruck Parse-Baum. Die Syntax wird im Top-Level-Kommentar für das Paket regexp beschrieben.

Es gibt sogar eine helper für Ihre Aufgabe.

EDIT1: Ihr Code repariert:

package main 

import "fmt" 

const sample string = `/(?P<country>m((a|b).+)(x|y)n)/(?P<city>.+)` 

func main() { 
     extract(sample) 
} 

func extract(regex string) { 
     var last4 [4]int32 
     for _, c := range regex { 
       last4[0], last4[1], last4[2], last4[3] = last4[1], last4[2], last4[3], c 
       last4String := fmt.Sprintf("%c%c%c%c", last4[0], last4[1], last4[2], last4[3]) 
       if last4String == "(?P<" { 
        fmt.Println("start of capturing group") 
       } 
     } 
} 

(auch here)

EDIT2: Ihr Code neu geschrieben:

package main 

import (
     "fmt" 
     "strings" 
) 

const sample string = `/(?P<country>m((a|b).+)(x|y)n)/(?P<city>.+)` 

func main() { 
     extract(sample) 
} 

func extract(regex string) { 
     start := 0 
     for { 
       i := strings.Index(regex[start:], "(?P<") 
       if i < 0 { 
         break 
       } 

       fmt.Printf("start of capturing group @ %d\n", start+i) 
       start += i + 1 
     } 
} 

(auch here)

Verwandte Themen