使用Go语言进行文本处理
编程语言特性
字符串的表示
双引号包围。支持多行字符串,使用反引号包围:
1 2 3 |
str := `This string will have tabs in it` |
切片操作
1 2 3 4 5 |
str := "12345" println(str[0:1]) // 1 println(str[0:4]) // 1234 println(str[:]) // 12345 println(str[1:]) // 12345 |
获取长度
built-in库支持对多种数据类型获取长度,包括字符串:
1 |
len("hello") |
取字符
1 |
str[idx] |
类型转换
1 2 3 4 5 6 |
var s string = "this is a string" var b []byte // 字符串转换为byte切片 b = []byte(s) // byte切换转换为字符串 s = string(b) |
相关包
strings
提供基本的字符串处理函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
strings.Contains("test", "es") // 包含子串测试 strings.Count("test", "t") // 子串出现个数测试 strings.HasPrefix("test", "te") // 前缀测试 strings.HasSuffix("test", "st") // 后缀测试 strings.Index("test", "e") // 获取起始位置 strings.Join([]string{"a", "b"}, "-") // 连接数组为字符串 strings.Repeat("a", 5) // 重复N次 strings.Replace("foo", "o", "0", -1) // 子串替换 strings.Split("a-b-c-d-e", "-") // 字符串分割 strings.ToLower("TEST") // 大写转换 strings.ToUpper("test") // 小写转换 strings.NewReader("str") // 获取一个Reader strings.TrimSpace(" str \n") // 返回去除首尾所有Unicode空白符后的切片 |
bytes
可以利用此包创建字符串缓冲区,类似于Java的StringBuffer:
1 2 3 4 5 6 7 |
var buffer bytes.Buffer for i := 0; i < 1000; i++ { buffer.WriteString("hello") } fmt.Println(buffer.String()) |
bufio
此包提供的Scanner可以逐行迭代处理字符串:
1 2 3 4 |
scanner := bufio.NewScanner(strings.NewReader(str))) for scanner.Scan() { buf.WriteString(scanner.Text()) } |
strconv
可用于将任何类型转换为字符串:
1 2 |
i := 123 t := strconv.Itoa(i) |
math/rand
可以创建随机字符串:
1 2 3 4 5 6 7 8 9 10 11 |
var source = rand.NewSource(time.Now().UnixNano()) const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" func RandString(length int) string { b := make([]byte, length) for i := range b { b[i] = charset[source.Int63()%int64(len(charset))] } return string(b) } |
bufio
可以实现逐行处理:
1 2 3 4 5 6 7 8 9 10 |
var ( reader *bufio.Reader = bufio.NewReader(strings.NewReader(value)) isPrefix bool = false line []byte = nil err error = nil ) for !isPrefix && err == nil { line, isPrefix, err = reader.ReadLine() println(string(line)) } |
fmt
用于进行C风格的字符串格式化。动词列表:
动词 | 说明 | 动词 | 说明 |
%v | 默认格式下的值 | %#v | Go语法格式下的值 |
%T | Go语法格式下的类型 | %% | 输出% |
%t | 输出Bool值 | %b | 二进制 |
%c | 输出Unicode代码点对应的字符 | %d | 十进制 |
%o | 八进制 | %O | 前缀0od的八进制 |
%q | 单引号包含的字符,已经安全转义 | %x | 十六进制,使用小写字母 |
%X | 十六进制,使用大写字母 | %U | Unicode格式,U+1234 |
%e | 科学计数法,小写e | %E | 科学计数法,大写E |
%f | 浮点数 | %F | 浮点数 |
%g | 自动选择%f或%e | %G | 自动选择%F或%E |
%s | 字符串或切片未解释的枝节 | %q | 双引号包含的字符,已经安全转义 |
%x | 十六进制,每字节显示为2小写字母 | %X | 十六进制,每字节显示为2大写字母 |
%p | 切片首元素的地址,指针地址 |
对于浮点数,可以指定精度:
示例 | 说明 |
%f | 默认宽度,默认精度 |
%9f | 宽度8,默认精度 |
%.2f | 默认宽度,精度2 |
%9.2f | 宽度9,精度2 |
%9.f | 宽度9,精度0 |
示例:
1 |
fmt.Sprintf("%6.2f", 12.0) |
正则式
包regexp实现了正则式搜索和匹配。Go语言使用类似Perl/Python等语言的正则式,所有字符都是UTF-8编码的代码点。
编译正则式
1 |
validMobileNo := regexp.MustCompile(`((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\d{8}`) |
匹配字符串
如果目标字符串匹配正则式,则返回true:
1 2 |
println(validMobileNo.MatchString("Tel: 18888888888")) //true println(validMobileNo.MatchString("188")) //false |
查找字符串
在目标字符串中检索并返回匹配正则式的子串:
1 |
println(validMobileNo.FindString("Tel: 18888888888 ")) // 18888888888 |
也可以返回匹配子串的索引范围,如果不匹配返回nil:
1 |
fmt.Println(validMobileNo.FindStringIndex("18888888888 ")) // [0 11] |
分组查找
返回整个匹配的子串,以及每个分组:
1 2 3 4 5 |
// 分组1 分组2 love := regexp.MustCompile(`([A-Z][a-z]+)\s+loves\s+([A-Z][a-z]+)`) fmt.Printf("%q\n", love.FindStringSubmatch("Alex loves Meng")) // 整个子串 分组1 分组2 // ["Alex loves Meng" "Alex" "Meng"] |
替换字符串
用字面值替换:
1 2 |
alex := regexp.MustCompile(`(Alex)`) println(alex.ReplaceAllLiteralString("Hello Alex", "${1}Wong")) // Hello ${1}Wong |
用捕获的分组替换:
1 |
println(alex.ReplaceAllString("Hello Alex", "${1} Wong")) // Hello Alex Wong |
Leave a Reply