首页 > 解决方案 > 识别 Python 中的字符集

问题描述

我在解析大约 20 亿行字符串时遇到了挑战,同时我想识别和分类使用的最大字符范围

输入:

示例 1:“456624”

示例 2:“generalkenobi”

示例 3:“海军上将!2”

输出

示例 1:10 个字符 (0123456789)

示例 2:26 个字符 (AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz

示例 3:96 字符 (0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz !"#$%&'()*+,-./:;<=>?@[]^_`{|}~)

有什么简单的方法可以做到这一点,直到现在我已经尝试了不同版本的 if 和isdigit(), islower(), isupper()andstring.punctuation

标签: pythonpython-3.x

解决方案


将字符分组为“集合”有许多不同且任意的方法——但一种常见的方法是将它们的底层数字编码阻止到范围内。因此ASCII(方便地,UTF-8 继承了这些映射等等)例如将可打印的字母、数字和标点字符设置为 32 到 127 之间的数字。

32 - 47 空格和标点符号
48 - 57 数字 0 - 9
58 - 64 更多标点符号
65 - 90 个大写字母字符
95 - 96 更多标点符号
97 - 122 个小写字母字符
123 - 127 更多标点符号。

此基本集的扩展也连续编号,并涵盖其他语言全新字母表和某些情况下失传已久的 文明中的附加变音符号。只需习惯 UTF-8(以及后来的 UTF-16)规范以及您想要分割的数字块,并查看用于对您正在查看的字符串进行编码的原始字节。

不过,首先,介于 32 和 127 之间的 ASCII 字符集应该为您提供工作的起点。

您可以将数据加载为原始字节并读取每个字节的数值以获取这些数字范围,或者加载到字符串中并用于your_string.encode("utf-8")获取数字字节值的等效列表。这些应该倾向于落入此处描述的范围内。

您可以管理一组字节范围以满足您的要求,包括或排除特定字符,具体取决于您自己的要求。

或者,如果您愿意留在字符串领域,只需将您的字符集设置为有效字符的集合,并与使用函数的字符集进行匹配。

就像是:

char_d = { "upper_case_alpha" : "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 
           "lower_case_alpha" : "abcdefghijklmnopqrstuvwxyz",
           "full_alphabet"    : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
           "digits"           : "0123456789" }

def tag_charsets(some_string, char_set_map):
    matching_tags = []
    for n,s in char_set_map.items():
        if all([c in s for c in some_string if c != " "]): # Explicitly excluding a space character from the match
            matching_tags.append(n)
    return matching_tags

tag_charsets("Mary had a little lamb", char_d)

应该返回一个列表,其中包含:

["full_alphabet"]

尽管,

tag_charsets("mary had a little lamb", char_d)

将返回:

['lower_case_alpha', 'full_alphabet']

因为这两个集合都在修改后的小写字符串中找到。

在这里,如果整个字符串都符合,我只会标记给定的字符集。您的用例可能有更方便的方法,但您可以轻松地编辑逻辑以执行您想要的任何操作。例如,您可能希望选择对给定字符串有效的最具体的单个“集合”。


推荐阅读