6

単純なパーサーを作成するために、文字列内の名前付きキャプチャグループの先頭を見つけようとしています(関連する質問を参照)。これを行うために、関数は変数extract内の文字の最後を記憶します。last4最後の4文字が「(?P <」」と等しい場合、それはキャプチャグループの始まりです。

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<"印刷すると、このサブストリンが出力に表示されますが、trueになることはありません。last4StringGoで文字列を比較する方法は?

そして、int32配列を文字列に変換するより洗練された方法はありfmt.Sprintf("%c%c%c%c\n", last4[0], last4[1], last4[2], last4[3])ますか?

他にもっと良いものはありますか?私のコードは私にはややエレガントに見えません。

4

1 に答える 1

3

独学などではない場合は、標準ライブラリにある既存のREパーサーを使用してから、ASTを「ウォーク」して必要な処理を実行することをお勧めします。

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

Parseは、指定されたFlagsによって制御される正規表現文字列sを解析し、正規表現解析ツリーを返します。構文は、パッケージregexpのトップレベルのコメントで説明されています。

あなたの仕事のためのヘルパーさえあります。

編集1:あなたのコードは修復されました:

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

ここにも)

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

ここにも)

于 2012-11-11T21:32:16.787 に答える