
本文介绍在 go 中高效过滤掉包含指定子字符串的文本行,通过正则表达式实现类似 ruby `reject { |r| r.include? 'substring' }` 的语义,并兼顾跨平台换行符(`\n`/`\r\n`)和边界匹配准确性。
在 Go 中处理文本行过滤时,由于标准库不提供类似 Ruby 的链式 split → reject → join 高阶操作,需结合 strings 包或正则表达式手动实现。最简洁、鲁棒的方式是使用 regexp 包配合多行模式((?m)),精准匹配整行并移除。
以下是一个完整可运行的示例:
package main
import (
"fmt"
"regexp"
)
func removeLinesContaining(s, substr string) string {
// 构造正则:多行模式下,匹配以任意换行符开头(可选)、包含 substr 的整行(含其后的换行符)
// 使用 [\r\n]+ 适配 \n 和 \r\n;^ 和 $ 在 (?m) 下匹配行首/行尾
pattern := "(?m)^.*" + regexp.QuoteMeta(substr) + ".*$[\r\n]*"
re := regexp.MustCompile(pattern)
return re.ReplaceAllString(s, "")
}
func main() {
input := `aaaaa
bbbb
cc substring ddd
eeee
ffff
ggg\r\nhh substring ii\r\njjj`
result := removeLinesContaining(input, "substring")
fmt.Println(result)
}输出:
aaaaa bbbb eeee ffff ggg jjj
✅ 关键要点说明:
- (?m) 启用多行模式,使 ^ 和 $ 分别匹配每行开头与结尾(而不仅是整个字符串首尾);
- [\r\n]* 匹配行尾换行符(支持 \n、\r\n 或孤立 \r),* 确保末尾无换行符的行也能被正确清理;
- regexp.QuoteMeta(substr) 对子字符串进行转义,防止其中含正则元字符(如 .、*、[)导致意外匹配;
- 若输入为 []byte,可改用 re.ReplaceAll(s, []byte("")),避免字符串与字节切片间反复转换。
⚠️ 注意事项:
- 正则方式简洁,但对超大文本(GB 级)可能存在性能开销;此时建议逐行扫描(strings.Split + strings.Contains + strings.Join),内存可控且逻辑更直观;
- 若需保留原始换行符一致性(如统一转为 \n),可在最后调用 strings.ReplaceAll(result, "\r\n", "\n")。
综上,正则方案适合中小规模文本、追求代码简洁性;流式逐行处理更适合大数据量或严格内存控制场景。两者皆可封装为通用函数,按需选用。










