#csv #records #transform #ruleset #quickly #sanity #rules

程序+库 csv-sanity

快速高效地清理和转换包含数百万记录的大型 CSV 文件

1 个不稳定版本

使用旧的 Rust 2015

0.1.0 2019 年 2 月 6 日

#1085文本处理

MPL-2.0 许可证

49KB
988

csv-sanity

在一个充满格式错误、验证不良的 CSV 文件的世界中保持你的理智。快速高效地清理和转换包含数百万记录的大型 CSV 文件。

注意: csv-sanity 处于 alpha 状态,可能会发生破坏性更改。特别是规则集文件语法可能在不久的将来发生变化。我亲自在多个项目中使用了 csv-sanity,它非常有帮助,但与大多数 alpha 软件一样,csv-sanity 是按原样提供的,不提供任何保证或保修。请自行承担风险,并仔细检查转换后的文件!

目的

CSV 格式没有很好地标准化,在存储具有复杂数据格式的大量记录时存在许多不足,但 CSV 作为大多数 CRM 和数据库软件可以解析和理解的通用交换格式在许多领域无处不在。

但是,当你的 CRM 只能解析 ISO 8601 格式的日期,而你继承的 CSV 中的日期格式如下时会发生什么

id,name,signup_date
2,John Doe,11/22/2017
3,Jane Doe,11/28/2017

或者你收到了一个需要通过个性化电子邮件联系的人的 CSV 文件,但 CSV 中的联系人姓名全部大写

id,first_name,last_name
2,JOHN,DOE
3,JANE,DOE

或者你有一个 CSV 文件,其中大多数记录具有有效值,但每 20k 个记录中有 1 个无意义的值导致整个导入中断

id,fist_name,last_name,party_registration
2,Jane,Doe,REP
3,John,Doe,DEM
345,Josh,Smith,HAHAHAHA

或者甚至有一个由于未转义逗号而格式不正确的 CSV 文件

id,first_name,last_name,email
2,Jane,Doe,jane@example.com
3,John,Doe,"i,don't,follow,the,rules"@example.com

这些都是我多年来遇到的真实问题。如果 CSV 足够小,可以通过手动修改来纠正,但对于具有 10k、100k 或甚至数百万记录的 CSV,手动修改根本不是可行的选择。

csv-sanity 旨在解决清理大型、验证不良的 CSV 文件的问题。

用法

csv-sanity 是一个可执行文件,它接受要处理的输入 CSV 文件和一个定义要应用转换规则的 JSON 规则集文件

csv-sanity [-r RULESET_FILE] <INPUT_FILE>

如果没有通过 -r 选项提供规则集文件的路径,csv-sanity 将在当前目录中查找名为 "ruleset.json" 的文件。

默认情况下,csv-sanity 将在当前目录中输出两个文件:output.csv,包含经过验证和转换的记录的处理后的CSV文件,以及errors.csv,包含无法处理的记录和字段列表以及它们被拒绝的原因。输出和错误文件的路径可以通过-o FILE_PATH-e FILE_PATH选项分别覆盖。

ruleset.json 语法

规则集文件是JSON文件,用于定义一组转换规则以及它们应该应用到的字段。

以下是一个示例规则集JSON文件

{
    "rules": [
        {
            "applicability": {
                "Global": [],
            },
            "transformer": {
                "None": {
                    "regex": "\\A(?:[:cntrl:]|\\s)*\\z"
                }
            },
            "priority": -10
        },
        {
            "applicability": {
                "Global": [],
            },
            "transformer": {
                "Trim": {}
            },
            "priority": -10
        },
        {
            "applicability": {
                "Fields": {
                    "field_names": [
                        "first_name",
                        "last_name"
                    ]
                }
            },
            "transformer": {
                "Capitalize": {}
            }
        }
    ]
}

每个ruleset.json文件都是一个包含单个"rules"字段的JSON对象,该字段包含一个规则对象数组。

规则是具有两个字段的对象

  • "applicability":指定规则是全局应用还是仅应用于预定义的一组字段(指定为正在处理的CSV中的列标题)
  • "transformer":转换器对象,用于指定应如何转换适用的字段。

转换器

大写

{
    "Capitalize": {}
}

将字符串字段转换为大写。

选择

{
    "Choice": {
        "choices": [
            "A",
            "B",
            "C"
        ]
    }
}

仅接受预定义的接受值列表,并拒绝其余的值。

日期

{
    "Date": {
        "input_formats": [
            "%m/%d/%Y"
        ],
        "output_formats": "%F"
    }
}

尝试通过time::strptime使用一系列日期时间格式解析字段。有关日期时间格式语法的详细信息,请参阅time crate的文档。

电子邮件

{
    "Email": {}
}

尝试将字段解析为电子邮件地址,拒绝任何看起来无效的电子邮件地址的字段。

{
    "None": {
        "regex": "\\A(?:[:cntrl:]|\\s)*\\z"
    }
}

将匹配的字段替换为空白值。在CSV文件中用作全局规则以规范化空白字段很有用。

数字

{
    "Number": {}
}

尝试将字段解析为整数,拒绝无法解析的字段。

电话号码

{
    "PhoneNumber": {}
}

尝试将文件解析为美国、NANP格式的电话号码,并将它们转换为标准国际格式+1 <area_code> <exchange_code> <subscriber_number>

正则表达式

{
    "Regex": {
        "regex": "\\A([A-Z])[A-Z]+\\z",
        "template": "$1"
    }
}

将字段与提供的正则表达式模式进行匹配,并根据模板字符串进行转换,替换捕获组占位符。有关正则表达式crate文档中的Regex::replace的详细信息。

正则表达式匹配

{
    "RegexMatch": {
        "regex": "\\A[A-Z]{2,3}\\z",
        "negate": false
    }
}

拒绝任何无法与提供的正则表达式模式匹配的字段。如果negatetrue,则拒绝任何与提供的正则表达式模式匹配的字段。

修剪

{
    "Trim": {}
}

从字段中删除前导和尾随空格。用作全局规则以规范字段和删除无用空格很有用。

邮政编码

{
    "Zipcode": {}
}

尝试将字段解析为美国邮政编码,格式为"xxxxx"和"xxxxx-xxxx",拒绝任何无法匹配该格式的字段。

依赖关系

~8MB
~148K SLoC