Help us shape the future of Go! Take the 2026 Go Developer Survey

stringx

package
v0.29.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 11 Imported by: 8

Documentation

Overview

Package stringx 提供常用的字符串操作工具函数。

包含字符串查找、过滤、截取、反转、大小写转换、多模式替换 (Replacer trie 最长匹配 / NewMask 敏感词遮罩)等功能。 所有函数均安全处理 UTF-8 编码的字符串。

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidStartPosition indicates the start position is invalid.
	ErrInvalidStartPosition = errors.New("start position is invalid")
	// ErrInvalidStopPosition indicates the stop position is invalid.
	ErrInvalidStopPosition = errors.New("stop position is invalid")
	// ErrInvalidRange indicates the substring range is inverted (start > stop).
	ErrInvalidRange = errors.New("substring range is inverted")
)

Functions

func Contains

func Contains(list []string, str string) bool

Contains 检查 str 是否在 list 中。

func ContainsAny

func ContainsAny(text string, keywords ...string) bool

ContainsAny 检查 text 中是否包含 keywords 中的任意一个关键词(不区分大小写)。

用法:

stringx.ContainsAny("Security vulnerability found", "security", "vuln") // true
stringx.ContainsAny("normal text", "critical", "major")                 // false

func Filter

func Filter(s string, filter func(r rune) bool) string

Filter 从 s 中过滤掉满足 filter 条件的字符。

func FirstN

func FirstN(s string, n int, ellipsis ...string) string

FirstN 返回 s 的前 n 个字符,可选添加省略号。

func FormatTemplate

func FormatTemplate(template string, vars map[string]any) string

FormatTemplate 用 vars 替换 template 里的 {key} 占位符。

模板语法: `{key}` 形式,key 在 vars 里查找。

  • 未找到的 key 保留原 `{key}` 不替换(避免静默替换空字符串导致歧义)
  • 嵌套 key 不支持(只 1 层)
  • 业务场景: 错误信息模板("user {user_id} not found in tenant {tenant_id}") SQL 模板("SELECT * FROM users WHERE id = {id}"),log 模板

用法:

msg := stringx.FormatTemplate("user {user_id} not found", map[string]any{
    "user_id": 42,
})
// → "user 42 not found"

注意: 这个函数不转义;如果业务需要把用户输入嵌入 SQL/HTML,先做 业务自己的转义/参数化(否则是注入漏洞)。

func GenerateID

func GenerateID() string

GenerateID 生成基于时间戳的唯一 ID,格式: 20060102150405-<8位hex>。 适用于非严格唯一性要求的场景(如日志关联、临时标识)。 如需全局唯一,请使用 uuid。

func HasEmpty

func HasEmpty(args ...string) bool

HasEmpty 检查 args 中是否存在空字符串。

func IndentText

func IndentText(text, prefix string) string

IndentText 为多行文本的第二行及之后每行添加缩进前缀。 第一行不缩进,适用于续行对齐场景。

用法:

stringx.IndentText("line1\nline2\nline3", "  ")
// => "line1\n  line2\n  line3"

func Join

func Join(sep byte, elem ...string) string

Join 将多个字符串用 sep 连接,忽略空字符串。

func JoinByComma

func JoinByComma(str []string) string

JoinByComma 将字符串切片用逗号连接。

func JoinWith

func JoinWith(elem []string, sep string) string

JoinWith 将字符串切片用指定分隔符连接。

func NotEmpty

func NotEmpty(args ...string) bool

NotEmpty 检查 args 中所有字符串是否都不为空。

func Pluralize

func Pluralize(count int, word string) string

Pluralize 返回英文单词的复数形式。 规则:

  • count == 1 → "1 word"
  • 以 "y" 结尾且前一个字符为辅音 → 去 "y" 加 "ies" (story → stories)
  • 以 "s", "sh", "ch", "x", "z" 结尾 → 加 "es" (box → boxes)
  • 其他 → 加 "s" (file → files)
  • word 为空 → "<count> "(计数仍然保留)

用法:

stringx.Pluralize(3, "file")   // "3 files"
stringx.Pluralize(1, "file")   // "1 file"
stringx.Pluralize(5, "story")  // "5 stories"

func Remove

func Remove(list []string, strs ...string) []string

Remove 从 strings 中移除指定的 strs。

func Reverse

func Reverse(s string) string

Reverse 反转字符串。

func SplitByComma

func SplitByComma(str string) []string

SplitByComma 将字符串按逗号分割。

func SplitCSVNonEmpty added in v0.22.0

func SplitCSVNonEmpty(s string) []string

SplitCSVNonEmpty 按逗号拆分字符串,逐项去掉首尾空白并丢弃空项。

与 SplitByComma 的区别:SplitByComma 就是 strings.Split(s, ",")——不 trim、 不过滤空项、空串返回 [""](1 个空元素),名字叫「按逗号拆」但实际把 「拆完顺手清干净」这层留给每个消费方各写一遍(典型样板:strings.Split → 逐项 TrimSpace → 跳过空项)。本原语把那层样板一次收进去。

与 SplitWith 的区别(不要拿 SplitWith 顶替):SplitWith 走 strings.Fields, 按**空白**切分,值里含空格时(如 glob 列表 "my glob")会被静默拆成两项, 改变语义。CSV 值的空白是有意义的("a b" 是一个值,不是两个),所以这条 面需要按逗号切的专门原语,而不是拿现有函数拼。

口径(写死在本函数契约里):

  • 逐项去掉**首尾**空白(strings.TrimSpace,含 Unicode 空白);
  • 去掉空白后为空的项**丢弃**("a,,b" → ["a","b"]);
  • **空串返回 nil**(不是空切片)——调用方普遍用 != nil / len()>0 区分 「没配」与「配了空」,返回空切片会把两者混同;
  • 全是空白或空项的输入(""、" "、",,")同样返回 nil。

用法:

stringx.SplitCSVNonEmpty("a, b,,c")  // ["a" "b" "c"]
stringx.SplitCSVNonEmpty("a,,b")     // ["a" "b"]
stringx.SplitCSVNonEmpty("")         // nil
stringx.SplitCSVNonEmpty("  ,  ")     // nil

func SplitWith

func SplitWith(str string, sep []string) []string

SplitWith 将字符串按指定分隔符列表分割后返回字段切片。

func Substr

func Substr(str string, start, stop int) (string, error)

Substr 返回 [start, stop) 范围内的子字符串,支持 UTF-8。

func TakeOne

func TakeOne(valid, or string) string

TakeOne 返回非空的字符串,如果 valid 非空则返回 valid,否则返回 or。

func TakeWithPriority

func TakeWithPriority(fns ...func() string) string

TakeWithPriority 返回第一个非空的函数返回值。

func ToCamelCase

func ToCamelCase(s string) string

ToCamelCase 将字符串首字母转为小写。

按 rune 处理(多字节首字符不被截断)。非法 UTF-8 字节不 panic:range 会把 非法字节解成 U+FFFD,其**实际**宽度是 1 字节,而 utf8.RuneLen(U+FFFD) 是 3 ⇒ 此前用 RuneLen 切片会越界(slice bounds out of range [3:1])。

func TruncBytes

func TruncBytes(s string, budget int) (string, bool)

TruncBytes 按字节预算截断(rune 对齐:预算落点切进多字节字符时回退到 RuneStart 边界,不产生非法 UTF-8 尾字节)。第二个返回值 = 是否真发生了 截断。budget<0 视为非法上限,按"全部截断"处理(返回空串),不 panic。

func TruncEllipsis

func TruncEllipsis(s string, n int) string

TruncEllipsis 截断并追加省略号(列表/标题/事件载荷展示面统一语义)。 n<=0 返回省略号;无需截断时原样返回。

**n 的语义是「截断到 n 个 rune」,不含省略号**:返回值长度为 n(未截断)或 n+1(发生截断,省略号算 1 个 rune)。若调用方的 n 是"总长度预算" (如提交状态描述的 140 字符上限),本函数会超出预算 1 个字符——那种场景用 TruncRunes 自行拼接,或先按预算减 1 再调用。

func TruncRunes

func TruncRunes(s string, n int) (string, bool)

TruncRunes 按 rune 截断,避免多字节字符被腰斩产生非法 UTF-8。 第二个返回值 = 是否真发生了截断。n<0 视为非法上限,按"全部截断"处理 (返回空串),不 panic。

func Union

func Union(first, second []string) []string

Union 合并两个字符串切片并去重。

Types

type Masker added in v0.16.0

type Masker struct {
	// contains filtered or unexported fields
}

Masker 形态脱敏器。

构造后只读,可安全并发使用。

func NewMasker added in v0.16.0

func NewMasker(rules []Rule) (*Masker, error)

NewMasker 创建形态脱敏器。

规则表由调用方完全提供,库不内置任何业务词表。返回 error 的情形:

  • Re == nil;
  • Name 为空;
  • Name 重复(形态标签重复会让审计结果有歧义);
  • Name 含定界符 '«' / '»' 或控制字符(输出将无法稳定解析);
  • Keep 为负数。

规则表为空(nil)时返回可用的空脱敏器,Mask 原样返回输入。

Example
rules := []Rule{
	{Name: "kv-secret", Re: regexp.MustCompile(`token=([^\s]+)`), Keep: 2},
}
m, err := NewMasker(rules)
if err != nil {
	fmt.Println("error:", err)
	return
}
fmt.Println(m.Mask("call api with token=abcdef123456"))
Output:
call api with to«kv-secret:****»56

func (*Masker) Mask added in v0.16.0

func (m *Masker) Mask(text string) string

Mask 对 text 做形态脱敏,返回打码后的文本。

打码是单次扫描合并:命中某条规则后,该段文本被替换为 head + «name:****» + tail(命中长度不足 Keep*4 时退化为 «name:****»), 替换结果不再参与任何规则的匹配。 未命中任何规则的文本原样保留。

type Replacer added in v0.7.0

type Replacer struct {
	// contains filtered or unexported fields
}

Replacer 多模式字符串替换器。 与 strings.Replacer 的差异:按 rune 对齐匹配(不撕裂 UTF-8), 且同一起点恒取最长匹配。

func NewMask added in v0.7.0

func NewMask(words []string, mask rune) (*Replacer, error)

NewMask 创建遮罩替换器:把 words 中每个词替换为等 rune 数的 mask 串。 用于敏感词遮罩场景,是 NewReplacer 的薄壳。

func NewReplacer added in v0.7.0

func NewReplacer(patterns, repls []string) (*Replacer, error)

NewReplacer 创建多模式替换器:patterns[i] 命中的子串替换为 repls[i]。 两者长度必须一致;空 pattern 或 nil patterns(不替换任何词)的处理见 返回值。同名 pattern 后写覆盖先写。

func (*Replacer) Replace added in v0.7.0

func (r *Replacer) Replace(text string) string

Replace 按 trie 最长匹配扫描 text 并替换。 按 rune 边界迭代:未命中的 rune 原字节保留(非法 UTF-8 序列不被 改写为 U+FFFD),命中的词整体替换。

type Rule added in v0.16.0

type Rule struct {
	// Name 形态标签,如 "url-userinfo";会原样出现在掩码里供审计读。
	// 不能为空、不能与同一规则表内其它规则的 Name 重复,也不能含定界符
	// '«' / '»' 或控制字符(否则输出无法被稳定解析)。
	Name string
	// Re 匹配待脱敏内容的正则。命中的**整段**文本被替换为掩码
	// (本库不区分捕获组,捕获组只影响匹配范围,不影响替换范围)。
	// 为 nil 时 NewMasker 报错。零宽匹配(空匹配)会被忽略。
	Re *regexp.Regexp
	// Keep 掩码保留首尾各几个字符作定位线索;0 = 全掩。
	// 语义是**封顶**:保留的字符数不随原值长度变化(见包内说明)。
	//
	// **命中长度不足 Keep*4 时整段全量打码(不做头尾保留)**——短值的头尾
	// 保留会首尾相接覆盖整段原文,原值会完整留在输出里,掩码形同虚设。
	// 调用方不必自己判断命中长度。
	//
	// 负数视为非法,NewMasker 报错。
	Keep int
}

Rule 一条脱敏规则。

规则表由调用方完全提供,库不内置任何词表:Re 负责「按形态认出」待脱敏 内容,Name 是形态标签(会出现在掩码里供审计读),Keep 控制保留的定位 线索位数。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL