首页 > 解决方案 > Python在字符串中的特殊字符存储不一致

问题描述

版本是 Python 3.7。我刚刚发现 python 有时会将字符 ñ 存储在具有多种表示形式的字符串中,我完全不知道为什么或如何处理它。

我不确定展示这个问题的最佳方式,所以我只展示一些代码输出。

我有两个字符串,s1 和 s2 都设置为相等'Dan Peña'

它们都是字符串类型。

我可以运行代码:

print(s1 == s2) # prints false
print(len(s1)) # prints 8
print(len(s2)) # prints 9
print(type(s1)) # print 'str'
print(type(s2)) # print 'str'
for i in range(len(s1)):
    print(s1[i] + ", " + s2[i])

循环的输出将是:

D, D
a, a
n, n
 ,  
P, P
e, e
ñ, n
a, ~

那么,是否有任何 python 方法来处理这些不一致,或者至少有一些关于 python 何时使用哪种表示的规范?

很高兴知道为什么 Python 会选择以这种方式实现。

编辑:

一个字符串是从 django 数据库中检索的,另一个字符串是从从 list dir 调用解析文件名获得的字符串。

from app.models import Model
from django.core.management.base import BaseCommand

class Command(BaseCommand):

    def handle(self, *args, **kwargs):
        load_dir = "load_dir_name"
        save_dir = "save_dir"

        files = listdir(load_dir)
        save_file_map = {file[:file.index("_thumbnail.jpg")]: f"{save_dir}/{file}" for file in files}
        for obj in Model.objects.all():
            s1 = obj.title
            save_file_path = save_file_map[s1] # Key error when encountering ñ.

但是,当我通过save_file_mapdict 搜索时,我发现一个与 s1 完全相同的键,除了 ñ 被编码为字符n~而不是 character ñ

请注意,我在上面的代码中使用 list dir 加载的文件首先基于 obj.title 字段命名,因此应保证具有该名称的文件在load_dir目录中。

标签: pythonpython-3.xstringpython-3.7unicode-normalization

解决方案


您需要对字符串进行规范化以使用相同的表示形式。现在,其中一个正在使用一个n字符 + 一个波浪号字符(2 个字符),而另一个正在使用一个表示带有波浪号的 n 的单个字符。

unicodedata.normalize应该做你想做的。请参阅此处的文档。

你会想这样称呼它:unicodedata.normalize('NFC', s1). 'NFC'告诉unicodedata.normalize您要对所有内容使用组合形式,例如. 除了 之外'NFC',文档中还提供了其他选项,您使用哪一个完全取决于您。

现在,您在什么时候进行标准化取决于您(我不知道您的应用程序是如何构建的)。例如,您可以在插入数据库之前进行规范化,或者在每次从数据库中读取时进行规范化。


推荐阅读