go标准包系列-文本包

1 strings包

1.1 字符串比较
  // Compare 函数,用于比较两个字符串的大小,如果两个字符串相等,返回为 0。如果 a 小于 b ,返回 -1 ,反之返回 1 。不推荐使用这个函数,直接使用 == != > < >= <= 等一系列运算符更加直观。
   func Compare(a, b string) int 
   //   EqualFold 函数,计算 s 与 t 忽略字母大小写后是否相等。
   func EqualFold(s, t string) bool
1.2 是否存在某个字符或子串
// 子串 substr 在 s 中,返回 true
func Contains(s, substr string) bool
// chars 中任何一个 Unicode 代码点在 s 中,返回 true
func ContainsAny(s, chars string) bool
// Unicode 代码点 r 在 s 中,返回 true
func ContainsRune(s string, r rune) bool
1.3 子串出现次数 ( 字符串匹配 )

在 Go 中,查找子串出现次数即字符串模式匹配,实现的是 Rabin-Karp 算法。Count 函数的签名如下:

func Count(s, sep string) int
1.4. 字符串分割为[]string
1.4.1 Fields 和 FieldsFunc
func Fields(s string) []string //空格以及多空格切割, 存粹空格数组返回长度为0
func FieldsFunc(s string, f func(rune) bool) []string //函数会遍历字符串 s 中的每个字符(使用 rune 类型表示),并根据回调函数 f 的返回值来确定分割的位置。当回调函数返回 true 时,表示在当前字符位置进行分割。

示例

// 自定义分割函数
f := func(c rune) bool {
	return unicode.IsSpace(c) || c == ',' || c == '.'
}

// 使用 FieldsFunc 进行字符串分割
words := strings.FieldsFunc(str, f)

// 打印分割后的子串
for _, word := range words {
	fmt.Println(word)
}
1.4.2 Split 和 SplitAfter、 SplitN 和 SplitAfterN
func Split(s, sep string) []string { return genSplit(s, sep, 0, -1) }
func SplitAfter(s, sep string) []string { return genSplit(s, sep, len(sep), -1) }
func SplitN(s, sep string, n int) []string { return genSplit(s, sep, 0, n) }
func SplitAfterN(s, sep string, n int) []string { return genSplit(s, sep, len(sep), n) }
1.5 字符串是否有某个前缀或后缀
// s 中是否以 prefix 开始
func HasPrefix(s, prefix string) bool {
  return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
}
// s 中是否以 suffix 结尾
func HasSuffix(s, suffix string) bool {
  return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
}
1.6 字符或子串在字符串中出现的位置
// 在 s 中查找 sep 的第一次出现,返回第一次出现的索引
func Index(s, sep string) int
// 在 s 中查找字节 c 的第一次出现,返回第一次出现的索引
func IndexByte(s string, c byte) int
// chars 中任何一个 Unicode 代码点在 s 中首次出现的位置
func IndexAny(s, chars string) int
// 查找字符 c 在 s 中第一次出现的位置,其中 c 满足 f(c) 返回 true
func IndexFunc(s string, f func(rune) bool) int
// Unicode 代码点 r 在 s 中第一次出现的位置
func IndexRune(s string, r rune) int

// 有三个对应的查找最后一次出现的位置
func LastIndex(s, sep string) int
func LastIndexByte(s string, c byte) int
func LastIndexAny(s, chars string) int
func LastIndexFunc(s string, f func(rune) bool) int
1.7. 字符串 JOIN 操作
func Join(a []string, sep string) string

自我实现

func Join(str []string, sep string) string {
  // 特殊情况应该做处理
  if len(str) == 0 {
      return ""
  }
  if len(str) == 1 {
      return str[0]
  }
  buffer := bytes.NewBufferString(str[0])
  for _, s := range str[1:] {
      buffer.WriteString(sep)
      buffer.WriteString(s)
  }
  return buffer.String()
}
1.8 字符串子串替换
// 用 new 替换 s 中的 old,一共替换 n 个。
// 如果 n < 0,则不限制替换次数,即全部替换
func Replace(s, old, new string, n int) string
// 该函数内部直接调用了函数 Replace(s, old, new , -1)
func ReplaceAll(s, old, new string) string
1.9 大小写转换
func ToLower(s string) string
func ToLowerSpecial(c unicode.SpecialCase, s string) string
func ToUpper(s string) string
func ToUpperSpecial(c unicode.SpecialCase, s string) string
1.10 标题处理
func Title(s string) string
func ToTitle(s string) string
func ToTitleSpecial(c unicode.SpecialCase, s string) string

标题处理包含 3 个相关函数,其中 Title 会将 s 每个单词的首字母大写,不处理该单词的后续字符。ToTitle 将 s 的每个字母大写。ToTitleSpecial 将 s 的每个字母大写,并且会将一些特殊字母转换为其对应的特殊大写字母。

2 bytes包

2.1 Runes 类型转换
// 将 []byte 转换为 []rune
func Runes(s []byte) []rune

该函数将 []byte 转换为 []rune ,适用于汉字等多字节字符,示例:

b:=[]byte("你好,世界")
for k,v:=range b{
    fmt.Printf("%d:%s |",k,string(v))
}
r:=bytes.Runes(b)
for k,v:=range r{
    fmt.Printf("%d:%s|",k,string(v))
}

运行结果:

0|1|2:  |3|4|5|6|7|8:  |9|10|11:  |12|13:  |14: |
0:你|1:好|2:,|3:世|4:界|
2.2 是否存在某个子 slice
// 子 slice subslice 在 b 中,返回 true
func Contains(b, subslice []byte) bool
2.3 []byte 出现次数
// slice sep 在 s 中出现的次数(无重叠)
func Count(s, sep []byte) int
2.4 Reader 类型
type Reader struct {
    s        []byte
    i        int64 // 当前读取下标
    prevRune int   // 前一个字符的下标,也可能 < 0
}

bytes 包下的 Reader 类型实现了 io 包下的 Reader, ReaderAt, RuneReader, RuneScanner, ByteReader, ByteScanner, ReadSeeker, Seeker, WriterTo 等多个接口。主要用于 Read 数据。

我们需要在通过 bytes.NewReader 方法来初始化 bytes.Reader 类型的对象。初始化时传入 []byte 类型的数据。NewReader 函数签名如下:

func NewReader(b []byte) *Reader

如果直接声明该对象了,可以通过 Reset 方法重新写入数据,示例:

x:=[]byte("你好,世界")

r1:=bytes.NewReader(x)
d1:=make([]byte,len(x))
n,_:=r1.Read(d1)
fmt.Println(n,string(d1))

r2:=bytes.Reader{}
r2.Reset(x)
d2:=make([]byte,len(x))
n,_=r2.Read(d2)
fmt.Println(n,string(d2))
2.5 Buffer 类型
type Buffer struct {
    buf      []byte
    off      int   
    lastRead readOp 
}

Buffer 可以通过 3 中方法初始化对象:

a := bytes.NewBufferString("Hello World")
b := bytes.NewBuffer([]byte("Hello World"))
c := bytes.Buffer{}

fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
}

输出结果:

Hello World
Hello World
{[] 0 0}

3 strconv包

3.1 strconv 包转换错误处理
3.2 字符串和整型之间的转换
func ParseInt(s string, base int, bitSize int) (i int64, err error)
func ParseUint(s string, base int, bitSize int) (n uint64, err error)
func Atoi(s string) (i int, err error)
3.2 整型转为字符串
func FormatUint(i uint64, base int) string    // 无符号整型转字符串
func FormatInt(i int64, base int) string    // 有符号整型转字符串
func Itoa(i int) string
3.3 字符串和布尔值之间的转换
// 接受 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False 等字符串;
// 其他形式的字符串会返回错误
func ParseBool(str string) (value bool, err error)
// 直接返回 "true" 或 "false"
func FormatBool(b bool) string
// 将 "true" 或 "false" append 到 dst 中
// 这里用了一个 append 函数对于字符串的特殊形式:append(dst, "true"...)
func AppendBool(dst []byte, b bool)
3.4 字符串和浮点数之间的转换
func ParseFloat(s string, bitSize int) (f float64, err error)
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
func AppendFloat(dst []byte, f float64, fmt byte, prec int, bitSize int)

4 unicode 包

unicode 包含了对 rune 的判断。这个包把所有 unicode 涉及到的编码进行了分类,使用结构

type RangeTable struct {
    R16         []Range16
    R32         []Range32
    LatinOffset int
}
func IsControl(r rune) bool  // 是否控制字符
func IsDigit(r rune) bool  // 是否阿拉伯数字字符,即 0-9
func IsGraphic(r rune) bool // 是否图形字符
func IsLetter(r rune) bool // 是否字母
func IsLower(r rune) bool // 是否小写字符
func IsMark(r rune) bool // 是否符号字符
func IsNumber(r rune) bool // 是否数字字符,比如罗马数字Ⅷ也是数字字符
func IsOneOf(ranges []*RangeTable, r rune) bool // 是否是 RangeTable 中的一个
func IsPrint(r rune) bool // 是否可打印字符
func IsPunct(r rune) bool // 是否标点符号
func IsSpace(r rune) bool // 是否空格
func IsSymbol(r rune) bool // 是否符号字符
func IsTitle(r rune) bool // 是否 title case
func IsUpper(r rune) bool // 是否大写字符
func Is(rangeTab *RangeTable, r rune) bool // r 是否为 rangeTab 类型的字符
func In(r rune, ranges ...*RangeTable) bool  // r 是否为 ranges 中任意一个类型的字符

5 utf8 包

utf8 里面的函数就有一些字节和字符的转换。

判断是否符合 utf8 编码的函数:

  • func Valid(p []byte) bool
  • func ValidRune(r rune) bool
  • func ValidString(s string) bool

判断 rune 所占字节数:

  • func RuneLen(r rune) int

判断字节串或者字符串的 rune 数:

  • func RuneCount(p []byte) int
  • func RuneCountInString(s string) (n int)

编码和解码到 rune:

  • func EncodeRune(p []byte, r rune) int
  • func DecodeRune(p []byte) (r rune, size int)
  • func DecodeRuneInString(s string) (r rune, size int)
  • func DecodeLastRune(p []byte) (r rune, size int)
  • func DecodeLastRuneInString(s string) (r rune, size int)

是否为完整 rune:

  • func FullRune(p []byte) bool
  • func FullRuneInString(s string) bool

是否为 rune 第一个字节:

  • func RuneStart(b byte) bool

示例:

word:=[]byte("界")

fmt.Println(utf8.Valid(word[:2]))
fmt.Println(utf8.ValidRune('界'))
fmt.Println(utf8.ValidString("世界"))

fmt.Println(utf8.RuneLen('界'))

fmt.Println(utf8.RuneCount(word))
fmt.Println(utf8.RuneCountInString("世界"))

p:=make([]byte,3)
utf8.EncodeRune(p,'好')
fmt.Println(p)
fmt.Println(utf8.DecodeRune(p))
fmt.Println(utf8.DecodeRuneInString("你好"))
fmt.Println(utf8.DecodeLastRune([]byte("你好")))
fmt.Println(utf8.DecodeLastRuneInString("你好"))

fmt.Println(utf8.FullRune(word[:2]))
fmt.Println(utf8.FullRuneInString("你好"))

fmt.Println(utf8.RuneStart(word[1]))
fmt.Println(utf8.RuneStart(word[0]))

运行结果:

false
true
true
3
1
2
[229 165 189]
22909 3
20320 3
22909 3
22909 3
false
true
false
true

6 utf16 包

utf16 的包的函数就比较少了。

将 uint16 和 rune 进行转换

func Encode(s []rune) []uint16
func EncodeRune(r rune) (r1, r2 rune)
func Decode(s []uint16) []rune
func DecodeRune(r1, r2 rune) rune
func IsSurrogate(r rune) bool // 是否为有效代理对

unicode 有个基本字符平面和增补平面的概念,基本字符平面只有 65535 个字符,增补平面(有 16 个)加上去就能表示 1114112 个字符。 utf16 就是严格实现了 unicode 的这种编码规范。

而基本字符和增补平面字符就是一个代理对(Surrogate Pair)。一个代理对可以和一个 rune 进行转换。

示例:

words :=[]rune{'𝓐','𝓑'}

u16:=utf16.Encode(words)
fmt.Println(u16)
fmt.Println(utf16.Decode(u16))

r1,r2:=utf16.EncodeRune('𝓐')
fmt.Println(r1,r2)
fmt.Println(utf16.DecodeRune(r1,r2))
fmt.Println(utf16.IsSurrogate(r1))
fmt.Println(utf16.IsSurrogate(r2))
fmt.Println(utf16.IsSurrogate(1234))

输出结果:

[55349 56528 55349 56529]
[120016 120017]
55349 56528
120016
true
true
false
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值