duanfuxing2417 2013-06-12 12:25
浏览 70

使用函数替换正则表达式子匹配

Let's say I have strings like

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

and I want to replace the parts between quotes in b:foo="hop" or b:bar="hu?" using a function.

It's easy to build a regular expression to get the match and submatch, for example

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

and then to call ReplaceAllStringFunc but the problem is that the callback receives the whole match and not the submatch :

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

How can I replace the submatch ?

Right now, I haven't found a better solution than to decompose myself m inside the callback with a regex, and to rebuild the string after having processed the submatch.

I would have used an alternate approach with a positive look behind were they available in Go but that's not the case (and they shouldn't be necessary anyway).

What can I do here?


EDIT : here's my current solution that I would like to simplify :

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

(playground link)

What bothers me is that I have to apply the regex twice. This doesn't sound right.

  • 写回答

1条回答 默认 最新

  • douchun1948 2013-06-12 12:49
    关注

    I don't like the code bellow, but it seems to do what you seem to want it to do:

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

    Playground


    Output

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

    EDIT: Take 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))
            }))
    }
    

    Playground


    Output:

    bla bla b:foo=computedFrom("hop") blablabla b:bar=computedFrom("hu?")
    
    评论

报告相同问题?

悬赏问题

  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题