使用简单的有限状态机处理 CSV 数据

本文介绍了一位开发者在处理CSV数据时遇到的问题,由于密码字段包含双引号导致解析困难。作者采用状态机的方法解决了这一问题,通过定义准备、判断和插入三种状态来解析包含双引号的字符串。提供的代码示例展示了如何实现这个状态机来正确读取和合并CSV中的数据。

  起因:因为最近生活的地方没有网络,导致 OneDrive 没有同步到 Keepass 密码数据库,出现了两份不一样数据库。为了合并这两个数据库,将其导出成 CSV 格式,然而在处理的时候遇到了个挺难受的坑。
  导出的 CSV 数据是 "abc","def","efg" 这种格式,咋一看感觉非常普通,没有任何问题。可是处理起来的时候却因密码字段中含有 " 字符(例如 "abc","d"ef","efg" ),导致 CSV 库不能正确读取 (也许可以正确处理,只是我忽略文档中的相关描述) ,然后改用正则去匹配,也遇到同样的问题。刚好最近看到了状态机相关的文章,便想着用状态机去解决这个问题。
  扯了挺多有的没的,说回代码本身。代码本身并不复杂,机器始终处于三种状态之一:

  • 准备状态:在这个状态时,若遇到 " 字符将忽略,并将自身状态设为 0 。这也是状态机的初始状态。
  • 判断状态: 当状态机接受 " 字符时,便进入 判断状态 ,直接跳过后续处理,接受下一个字符。若这个字符是 , ,则表明已经接受完一个字段,故将内存中暂存的所有字符合并,放入结果列表中,并将 准备状态 设为 1 。若不是,说明上一个 " 只是一个普通字符,于是将 " 放入内存中;然后判断新接受的字符是否为 " ,若是,则继续将 判断状态 设为 1
  • 插入状态:当接受到的字符既不是 " ,又不是 判断状态 下的 , 字符时,往内存中插入该字符。

除了这些外,还有一些行末尾之类的细节就不再赘述了,各位看官直接看代码便可。

class FakeList:
    def __init__(self, string: str):
        if len(string) == 0:
            raise RuntimeError('The length of the incoming string must be greater than or equal to 1 !')
        self.string = string
        self.index = 0
        self.max = len(self.string)

    def __bool__</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值