如何将正则表达式应用于文件(Go)中的内容?

时间:2015-02-18 01:48:42

标签: regex go

我正在使用io/ioutil包来读取文件:

package main

import (
    "fmt"
    "github.com/codegangsta/cli"
    "io/ioutil"
    "os"
    "regexp"
)

func main() {
    app := cli.NewApp()
    app.Name = "m2k"
    app.Usage = "convert markdown to kindle"

    app.Action = func(c *cli.Context) {
        file := "no file"

        if len(c.Args().First()) > 0 {
            file = c.Args().First()

            fmt.Println("worked:", file)

            b, err := ioutil.ReadFile(file)
            if err != nil {
                panic(err)
            }

            r, _ := regexp.Compile(b)
            fmt.Println(r.ReplaceAllString("oldtext", "newtext"))
        }

    }

    app.Run(os.Args)
}

// $ go run io2.go input.txt

// input.txt

// text text oldtext oldtext

我想将正则表达式应用于文件的内容:

r, _ := regexp.Compile(b)
mt.Println(r.ReplaceAllString("oldtext", "newtext"))

问题是似乎regexp.Compile不适用于byte类型:

  

./ io2.go:29:不能在函数中使用b(type [] byte)作为类型字符串   参数

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

regexp replace方法返回source参数,regexp匹配替换为replacement参数。因为应用程序正在用“newtext”替换“oldtext”,所以“oldtext”是regexp:

r, err := regexp.Compile("oldtext")

因为应用程序将文件的内容作为[]字节,所以ReplaceAll可以使用ReplaceAllString的insead。这确实需要将replacment字符串转换为[]字节,但这可能比将文件转换为ReplaceAllString的字符串要便宜。

r.ReplaceAll(b, []byte("newtext"))

ReplaceAll的结果是一个[]字节,可以直接写入stdout。没有必要fmt.Println输出。

这是完整的代码:

b, err := ioutil.ReadFile(file)
if err != nil {
  panic(err)
}

r, err := regexp.Compile("oldtext")
if err != nil {
  // handle error
}
os.Stdout.Write(r.ReplaceAll(b, []byte("newtext")))

答案 1 :(得分:3)

您似乎正在尝试将从文件中读取的内容编译为正则表达式。

以下语法可以解决您的问题。

x := string(b)
r, err := regexp.Compile("oldtext")
if err != nil {
    return // problem with the regular expression.
}
fmt.Println(r.ReplaceAllString(x, "newtext"))

但是,最好不要将二进制数据转换为字符串并直接使用它。