1. 判断一个字符串的前缀是否为另一个字符串
hasStrPrefix := strings.HasPrefix("jin tian tian qi hao", "jin tian")
源码:
func HasPrefix(s, prefix string) bool {
return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
}
s字符串的长度大于等于prefix字符串的长度 并且 s字符串截取0到 len(prefix) 是否为prefix
2. 判断一个字符串是否包含另一个字符串
hasContains := strings.Contains("jin tian tian qi hao", "tian qi")
源码:
func Contains(s, substr string) bool {
return Index(s, substr) >= 0
}
substr字符串在s字符串位置是否大于0
3. 返回字符串s中有几个不重复的sep子串。
count := strings.Count("jin", "")
源码:
func Count(s, substr string) int {
// special case
//如果子字符串为空
if len(substr) == 0 {
//返回s长度加1
//If substr is an empty string, Count returns 1 + the number of Unicode code points in s.
return utf8.RuneCountInString(s) + 1
}
//子字符串等于1时
if len(substr) == 1 {
//Go 语言编译指示 https://segmentfault.com/a/1190000016743220
return bytealg.CountString(s, substr[0])
}
n := 0
//开始循环
for {
//substr在s中位置
i := Index(s, substr)
//如果i==-1 就是s内没有substr时 直接返回n,第一次执行n是0
if i == -1 {
return n
}
//执行到这里说明s包含substr,n加1
n++
//s去掉substr部分 再次循环
s = s[i+len(substr):]
}
}
4. 子串sep在字符串s中第一次出现的位置,不存在则返回-1。
i := strings.Index("jin tian tian qi hao", "qi")
源码:
func Index(s, substr string) int {
//获取substr长度
n := len(substr)
switch {
case n == 0:
//substr长度为0返回0
return 0
case n == 1:
//如果是1时
return IndexByte(s, substr[0])
case n == len(s):
//长度相等时
//两个字符串相等 返回0
if substr == s {
return 0
}
return -1
case n > len(s):
return -1
case n <= bytealg.MaxLen:
// Use brute force when s and substr both are small
//当s和substr都很小的时候使用蛮力
//小于等于64
if len(s) <= bytealg.MaxBruteForce {
return bytealg.IndexString(s, substr)
}
//获取子字符串 第一个字符
c0 := substr[0]
//第二个字符
c1 := substr[1]
i := 0
//如果s包含substr, substr的第一个字符 c0 一定在s为 0 到 len(s) - n + 1 之间
t := len(s) - n + 1
//失败次数
fails := 0
for i < t {
//如果开始字符不相等
if s[i] != c0 {
// IndexByte is faster than bytealg.IndexString, so use it as long as
// we're not getting lots of false positives.
//查找首次位置
o := IndexByte(s[i:t], c0)
if o < 0 {
//没有返回 -1
return -1
}
//位置后移 出现的位置
i += o
}
//判断下是否相等
if s[i+1] == c1 && s[i:i+n] == substr {
return i
}
//加1
fails++
i++
// Switch to bytealg.IndexString when IndexByte produces too many false positives.
//失败次数达到一定次数 换个方法
if fails > bytealg.Cutover(i) {
r := bytealg.IndexString(s[i:], substr)
if r >= 0 {
return r + i
}
return -1
}
}
return -1
}
//类似上面
c0 := substr[0]
c1 := substr[1]
i := 0
t := len(s) - n + 1
fails := 0
for i < t {
if s[i] != c0 {
o := IndexByte(s[i:t], c0)
if o < 0 {
return -1
}
i += o
}
if s[i+1] == c1 && s[i:i+n] == substr {
return i
}
i++
fails++
if fails >= 4+i>>4 && i < t {
// See comment in ../bytes/bytes_generic.go.
j := indexRabinKarp(s[i:], substr)
if j < 0 {
return -1
}
return i + j
}
}
return -1
}
5. 返回s中每个单词的首字母都改为标题格式的字符串拷贝。
title := strings.Title("jin tian tian qi hao")
源码:
func Title(s string) string {
// Use a closure here to remember state.
// Hackish but effective. Depends on Map scanning in order and calling
// the closure once per rune.
prev := ' '
//Map 说明: 将s的每一个unicode码值r都替换为mapping(r),返回这些新码值组成的字符串拷贝。如果mapping返回一个负值,
// 将会丢弃该码值而不会被替换。(返回值中对应位置将没有码值)
return Map(
func(r rune) rune {
//如果前一个字符串分界
if isSeparator(prev) {
//当前r更新为prev
prev = r
//转换为大写
return unicode.ToTitle(r)
}
//返回原r
prev = r
return r
},
s)
}