parsing - 如何解析任意长度的文件?

标签 parsing go text

我有一个文本文件,我想用这样的记录来解析:

===================
name: John Doe
Education: High School Diploma
Education: Bachelor's Degree
Education: Sun Java Certified Programmer
Age: 29
===================
name: Bob Bear
Education: High School Diploma
Age: 18
===================
name: Jane Doe
Education: High School Diploma
Education: Bachelor's Degree
Education: Master's Degree
Education: AWS Certified Solution Architect Professional
Age: 25

如您所见,此类文本文件中的字段 是固定的,但其中一些字段会重复任意次数。记录由固定长度的 ==== 分隔符分隔。

对于这类问题,我该如何编写解析逻辑?我想在读取行首时使用 switch,但处理多个重复字段的逻辑让我感到困惑。

最佳答案

处理这类问题的一个好方法是“分而治之”。也就是说,将整个问题划分为更易于管理的更小的子问题,然后分别解决每个问题。如果您计划得当,那么当您完成每个子问题时,您应该已经解决了整个问题。

首先考虑建模。该文档似乎包含一个记录列表,这些记录应该叫什么?记录应包含哪些命名字段以及它们应具有哪些类型?你会如何在 go 中惯用地表示它们?例如,您可能决定将每条记录称为 Person,其字段如下:

type Person struct {
    Name        string
    Credentials []string
    Age         int
}

接下来,考虑一下您的解析函数的接口(interface)(签名)应该是什么样子。它应该发出一系列的人吗?它是否应该使用访问者模式并在解析后立即发出一个人?什么约束应该驱动答案?内存或计算时间限制重要吗?解析器的用户是否希望对解析工作进行任何控制,例如取消?他们是否需要元数据,例如文档中包含的记录总数?输入总是来自文件或字符串,可能来自 HTTP 请求或网络套接字?这些选择将如何插入您的设计?

func ParsePeople(string) ([]Person, error) // ?
func ParsePeople(io.Reader) ([]Person, error) // ?
func ParsePeople(io.Reader, func visitor(Person) bool) error // ?

最后,您可以实现您的解析器来实现您已决定的接口(interface)。这里一个直接的方法是逐行读取输入文件并根据行的内容采取行动。例如(伪代码):

forEach line = inputFile.line
  if line is a separator
    emit or store the last parsed person, if present
    create a new person to store parsed fields
  else if line is a data field
    parse the data
    update the person with the parsed data
  end
end
return the parsed records or final record, if emitting

上面的每一行伪代码代表一个子问题,应该比整个问题更容易解决。

关于parsing - 如何解析任意长度的文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51666916/

相关文章:

Python通过解析找出所有路径

Delphi:将对象传输到远程计算机

Golang - 如何运行引用包的命令

go - Go 有文件名限制吗?

algorithm - 判断多用户编辑文本 "Owner"

Python CSV 解析,转义引号字符

node.js bodyParser 错误

模板上的 Golang 函数调用在单个结构上失败

bash - 使用 bash 命令在列中创建编号集

linux - 在终端中输入空字符