2012-11-11 14 views
6

文字列内の名前付きキャプチャグループの先頭を探して、単純なパーサーを作成しようとしています(related question参照)。これを行うために、extract関数は、last4変数の最後の文字を覚えています。 「?(P <」最後の4つの文字が等しい場合には、キャプチャグループの始まりです!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

しかし、このコードは何も出力しないlast4String == "(?P<"このsubstrinが表示されますが、本当のことはありません出力で、私はループ内last4Stringを印刷する場合。どのようにして移動中の文字列を比較するには?

そしてfmt.Sprintf("%c%c%c%c\n", last4[0], last4[1], last4[2], last4[3])

よりも文字列にint32型の配列に変換するために、よりエレガントな方法があります

他に良いことがありますか?私のコードは、私にとってやや面白く見えます。

答えて

3

自己教育などでない場合は、標準ライブラリにある既存のRE parserを使用し、必要に応じてASTを「歩く」ことをお勧めします。

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

解析は、指定されたフラグによって制御される正規表現の文字列sを、解析し と正規表現の構文解析ツリーを返します。構文は、パッケージregexpの最上位コメント に記述されています。

あなたの仕事にはさらにhelperがあります。

EDIT1:あなたのコードが修復:

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

(またhere

EDIT2:あなたのコードの書き換え:

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

(またhere