text/scanner 用于 go 语法词法扫描,识别 ident、int 等 token,不支持自定义分隔符切分;需配合 tokentext() 获取字面量,错误处理需设 error 回调启用定位。

text/scanner 不是用来“扫描文本提取单词”的,它干的是词法扫描(lexical scanning)——识别 Go 语法风格的 token,比如 IDENT、INT、STRING、COMMENT。想按空格、逗号或自定义分隔符切字符串?别用它。
scanner.Scan() 返回的是 token 类型,不是字符串片段
调用 s.Scan() 后,返回值是 rune 类型,对应预定义常量如 scanner.IDENT、scanner.INT、scanner.COMMA 等;它不直接给你切好的子串。
- 必须立刻调用
s.TokenText()才能拿到原始字面量,比如输入"x := 42",s.Scan()返回scanner.IDENT后,s.TokenText()才是"x" - 如果跳过
TokenText()直接打印,或在多次Scan()后统一取,结果为空 —— 因为内部缓冲区已移位,旧内容被覆盖 -
s.Bytes()和s.Text()是bufio.Scanner的方法,text/scanner没有这两个 API
想按 "|||" 或换行切流?用 bufio.Scanner 配 SplitFunc
text/scanner 完全不处理用户自定义分隔符。它的 “分隔” 是语法驱动的:空白、注释、操作符本身都是独立 token,不是切点。
- 要实现类似 Python 的
str.split("|||")流式效果,必须用bufio.Scanner并调Split() - 自定义
SplitFunc必须处理两个关键边界:atEOF == true(最后一段没分隔符)、len(data) (数据未读全,不能贸然切) - 错误写法:
bytes.Index(data, []byte("|||"))后直接切,忽略atEOF→ 最后一段永远扫不到
遇到 scanner.ILLEGAL 却没报位置?装上 Error 回调
text/scanner 默认对非法字符(如损坏 UTF-8、控制字符)静默吞掉,只返回 scanner.ILLEGAL,连行号列号都不更新。
- 启用定位需手动设置
s.Error = func(s *scanner.Scanner, msg string) { ... } - 此时
s.Line和s.Column才反映错误发生处(注意:平时它们是上一个 token 结束位置,不是当前扫描点) - 常见非法源:含 BOM 的文件(
\xef\xbb\xbf)、Windows 换行符混入、二进制残留字节
配置 Mode 和 Whitespace 前先确认你要什么
Mode 是位掩码,决定识别哪些 token;Whitespace 控制哪些字符算“空白”(影响跳过行为)。但二者作用不同,别混淆。
- 想只识别标识符和整数?设
s.Mode = scanner.ScanIdents | scanner.ScanInts,别加ScanComments,否则注释会变成 token - 想保留制表符或换行符作为 token?得清空
Whitespace(如s.Whitespace = 0),否则默认的GoWhitespace会把它们全跳过 -
SkipComments和ScanComments互斥:前者让注释变为空白(不产出 token),后者让注释成为scanner.COMMENTtoken
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











