Golang 字符串处理,删除文件中的指定行

在Go语言中字符串处理操作,可用的内建包有strings、bytes、strconv、regexp、fmt等等吧,不管在任何语言中字符串处理、数组处理在日常开发中都是非常频繁的,当然了,Go语言中用的最多的是不数组而是slice切片,写这篇文章的目的不是记录标准库的常规操作,而是记录一些配合标准库处理字符串的技巧性操作,这篇文章不会一下记录所有的字符串处理场景,但是会持续性的更新,希望我这些遇到的字符串处理案例可以对您的开发工作有所帮助~

完成这个字符串场景处理需要使用到正则表达式,Go语言提供的标准库为regexp,以及文件操作。具体思路这样子的,读取文件内容,使用正则表达式去匹配指定字符串所在的行,然后删除即可,最后将处理后的字符串保存到文件,这个字符串处理场景需要也就完成了,来看具体的代码如何实现。

现在,在demo目录下有一个文本文件,如helloshaohua.txt内容如下:

1
2
3
4
$ cat ./demo/helloshaohua.txt
helloshaohua
WillDeleteLine
wu.shaohua@foxmail.com

可以看到,现在这个文件有3行,比如说想要删除 WillDeleteLine 这个特定字符串所在的行,让这个文件变为2行,最终的文件内容应该如下:

1
2
3
$ cat ./demo/helloshaohua.txt
helloshaohua
wu.shaohua@foxmail.com

这是我们预期想要达到的目标,有了这个简单的小场景需求,来编写具体的代码实现,在demo目录下创建demo.go具体如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package demo

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"regexp"
)

// DeleteFileSpecificContentLine Deletes lines of a file that contain specific content.
func DeleteFileSpecificContentLine(filename, findStr string) error {
	// Write file.
	bytes, err := ioutil.ReadFile(filename)
	if err != nil && os.IsNotExist(err) {
		return errors.New(fmt.Sprintf("%s file not exists", filename))
	}

	// Delete line.
	bytes = regexp.MustCompile(fmt.Sprintf(`%s\n`, findStr)).ReplaceAll(bytes, []byte(""))

	// Write file.
	return ioutil.WriteFile(filename, bytes, 0644)
}

并且在demo目录下创建了一个测试文件demo_test.go具体内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package demo

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestDeleteFileSpecificContentLine(t *testing.T) {
	err := DeleteFileSpecificContentLine("helloshaohua.txt", "WillDeleteLine")
	assert.NoError(t, err)
}

来跑一下demo目录下的这个测试:

1
2
3
4
5
$ go test -v ./demo
=== RUN   TestDeleteFileSpecificContentLine
--- PASS: TestDeleteFileSpecificContentLine (0.00s)
PASS
ok      github.com/helloshaohua/demo     0.459s

从测试结果来看,它已经成功了,来看一下demo目录下的helloshaohua.txt:

1
2
3
$ cat demo/helloshaohua.txt
helloshaohua
wu.shaohua@foxmail.com

现在它已经更改成了我们的预期文件内容。需要特别说明的就是在 demo.go 文件中,regexp.MustCompile这个函数具体会根据传递的参数具体编译,如,在当前的案例中传递的参数值为 WillDeleteLine,regexp.MustCompile函数最终编译的字符串为 WillDeleteLine\n,*Regexp.ReplaceAll函数是直接处理的字节切片,因为,ioutil.ReadFile函数读取的文件最终结果为字节切片,我们不需要将它转换为字符串就可以使用*Regexp.ReplaceAll函数进行处理,如果是字符串您可以选择使用字符串处理函数进行处理,如*Regexp.ReplaceAllString函数等等。

comments powered by Disqus