16

次のような文字列があるとしましょう

input := `bla bla b:foo="hop" blablabla b:bar="hu?"`

b:foo="hop"関数内または関数を使用して、引用符の間の部分を置き換えたいb:bar="hu?"

正規表現を作成して一致とサブマッチを取得するのは簡単です。たとえば、

r := regexp.MustCompile(`\bb:\w+="([^"]+)"`)

そして呼び出しますReplaceAllStringFuncが、問題は、コールバックがサブマッチではなくマッチ全体を受け取ることです:

fmt.Println(r.ReplaceAllStringFunc(input, func(m string) string {
    // m is the whole match here. Damn.
}))

サブマッチを置き換えるにはどうすればよいですか?

今のところ、m正規表現を使用してコールバック内で自分自身を分解し、サブマッチを処理した後に文字列を再構築するよりも良い解決策を見つけていません。

Go で利用できる場合は、肯定的な見方をする別のアプローチを使用していたでしょうが、そうではありません (とにかく必要ではないはずです)。

ここで何ができますか?


編集:ここに私が簡素化したい私の現在の解決策があります:

func complexFunc(s string) string {
   return "dbvalue("+s+")" // this could be more complex
}
func main() {
        input := `bla bla b:foo="hop" blablabla b:bar="hu?"`
        r := regexp.MustCompile(`(\bb:\w+=")([^"]+)`)
        fmt.Println(r.ReplaceAllStringFunc(input, func(m string) string {
                parts := r.FindStringSubmatch(m)
                return parts[1] + complexFunc(parts[2])
        }))
}

(遊び場リンク)

気になるのは、正規表現を 2 回適用する必要があることです。これは正しく聞こえません。

4

2 に答える 2

3

私は次のコードが好きではありませんが、あなたがやりたいと思うことをしているようです:

package main

import (
        "fmt"
        "regexp"
)

func main() {
        input := `bla bla b:foo="hop" blablabla b:bar="hu?"`
        r := regexp.MustCompile(`\bb:\w+="([^"]+)"`)
        r2 := regexp.MustCompile(`"([^"]+)"`)
        fmt.Println(r.ReplaceAllStringFunc(input, func(m string) string {
                return r2.ReplaceAllString(m, `"${2}whatever"`)
        }))
}

遊び場


出力

bla bla b:foo="whatever" blablabla b:bar="whatever"

編集:テイクII。


package main

import (
        "fmt"
        "regexp"
)

func computedFrom(s string) string {
        return fmt.Sprintf("computedFrom(%s)", s)
}

func main() {
        input := `bla bla b:foo="hop" blablabla b:bar="hu?"`
        r := regexp.MustCompile(`\bb:\w+="([^"]+)"`)
        r2 := regexp.MustCompile(`"([^"]+)"`)
        fmt.Println(r.ReplaceAllStringFunc(input, func(m string) string {
                match := string(r2.Find([]byte(m)))
                return r2.ReplaceAllString(m, computedFrom(match))
        }))
}

遊び場


出力:

bla bla b:foo=computedFrom("hop") blablabla b:bar=computedFrom("hu?")
于 2013-06-12T12:49:32.347 に答える