2012-11-11 19 views
6

Sto cercando di trovare l'inizio di un gruppo di acquisizione denominato in una stringa per creare un parser semplice (vedere related question). Per fare ciò, la funzione extract memorizza l'ultimo carattere per la variabile last4. Se gli ultimi 4 caratteri sono uguali a "(P <?" È l'inizio di un gruppo di cattura:!Confronto di stringhe 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

Ma questo stampe di codici a nulla last4String == "(?P<" non è mai vero, anche se appare questa substrin nell'output se stampo last4String all'interno del ciclo. Come confrontare le stringhe in Go allora?

E c'è un modo più elegante per convertire una matrice int32 in una stringa di fmt.Sprintf("%c%c%c%c\n", last4[0], last4[1], last4[2], last4[3])?

0.123.516,410617 millions

Qualcos'altro che potrebbe essere migliore? Il mio codice mi sembra poco elegante.

risposta

3

Se non è per l'autoeducazione o simili, probabilmente si desidera utilizzare lo RE parser esistente nella libreria standard e quindi "spostare" l'AST per fare tutto il necessario.

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

Parse analizza una stringa un'espressione regolare s, controllato dalle bandiere specificati, e restituisce un albero di espressione regolare di analisi. La sintassi è descritta nel commento di primo livello per il regexp del pacchetto.

C'è persino un helper per l'attività.

Edit1: Il tuo codice riparato:

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") 
       } 
     } 
} 

(anche here)

EDIT2: Il codice riscritto:

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 
     } 
} 

(anche here)