
本文介绍使用正则表达式在 go 中高效过滤掉包含特定子字符串的整行内容,适用于处理 `[]byte` 或 `string` 类型的多行文本,提供可直接运行的示例代码及关键注意事项。
在 Go 中删除包含指定子字符串的整行(即“过滤掉含关键词的行”),不能像 Ruby 那样直接按行切分再筛选,但可通过正则表达式的多行模式((?m))精准匹配并替换目标行。核心思路是:将每行视为独立上下文,用 ^ 和 $ 锚定行首与行尾,匹配整行中包含目标子串的内容,并将其替换为空字符串。
以下是一个完整、健壮的实现示例:
package main
import (
"fmt"
"regexp"
)
func removeLinesContaining(s, substr string) string {
// 构造正则:(?m) 启用多行模式;^.*substr.*$ 匹配整行含 substr 的行;[\r\n]* 适配行尾换行符(含空行)
pattern := "(?m)^.*" + regexp.QuoteMeta(substr) + ".*$[\r\n]*"
re := regexp.MustCompile(pattern)
return re.ReplaceAllString(s, "")
}
func main() {
s := `aaaaa
bbbb
cc substring ddd
eeee
ffff
g substring h`
result := removeLinesContaining(s, "substring")
fmt.Println(result)
}输出:
aaaaa bbbb eeee ffff
✅ 关键要点说明:
- 使用 (?m) 标志使 ^ 和 $ 同时匹配每行的开头和结尾,而非仅整个字符串首尾;
- regexp.QuoteMeta(substr) 对子字符串进行转义,防止其含正则元字符(如 ., *, $)导致意外匹配;
- [\r\n]* 紧跟 $ 后,用于清除被删行所占的换行符,避免残留空行(比仅用 [\r\n]+ 更安全,兼容末尾无换行的场景);
- 若原始数据为 []byte,可先转换为 string 处理(小数据无性能问题),或使用 regexp.ReplaceAll(b []byte, repl []byte) 方法操作字节切片。
⚠️ 注意事项:
- 正则方案简洁高效,适合中小规模文本;若需极致性能或处理超大文件(GB 级),建议改用流式逐行读取 + 条件写入;
- 不要忽略换行符处理——漏掉 [\r\n]* 可能导致相邻行被合并(如 "line1\nline2" → "line1line2");
- ReplaceAllString 返回新字符串,原内容不可变;如需原地修改 []byte,请使用 ReplaceAll 配合字节切片操作。
综上,该方法准确复现了 Ruby 中 reject { |r| r.include? 'xxx' } 的语义,在 Go 生态中兼具可读性、安全性与实用性。










