首页 > 解决方案 > 无法将大写字母变为“ß”(称为 eszett 的德语字符)

问题描述

您好,我必须将字符串列转换为其大写版本,但是当字符串中存在 'ß' 时,它会在大写时更改为 'SS' 我知道这是因为之前的 'SS' 被认为是大写的'ß'。但是在 2017 年,“SS”和大写“ß”都是允许的。

并且它的 unicode 版本也可用。

我对此有以下疑问:

  1. 为什么 python 不将其转换为大写的“ß”。

  2. 是因为嵌入在python中的unicode标准吗?如何知道使用的是哪个 unicode 标准 python/jupyter notebook?

  3. 无论如何在python中得到大写的'ß'而不是'SS'?

我是

标签: pythonunicodeutf-8character-encoding

解决方案


各种 Python 版本使用特定的 Unicode 版本。例如,我认为最初的 Python3.7使用 Unicode 10.0.0,虽然它可用的字母(我相信它从 Unicode 开始就有了5.1),但仍然列出了旧的上/下映射:

00DF ß LATIN SMALL LETTER SHARP S
    = Eszett
    - German
    - uppercase is "SS"
    - nonstandard uppercase is 1E9E ẞ
1E9E ẞ LATIN CAPITAL LETTER SHARP S
    - lowercase is 00DF ß

即使是本答案时的最新13.0.0标准(尽管此更改是在 中进行的11.0.0),似乎也允许自行决定如何将下限转换为上限:

00DF ß LATIN SMALL LETTER SHARP S
    = Eszett
    - German
    - not used in Swiss High German
    - uppercase is "SS" or 1E9E ẞ
1E9E ẞ LATIN CAPITAL LETTER SHARP S
    - not used in Swiss High German
    - lowercase is 00DF ß

下表将一些 Python 版本映射到 Unicode 版本:

 Python     Unicode
--------    -------
   3.5.9      8.0.0
  3.6.11      9.0.0
   3.7.8     11.0.0
3.8.4rc1     12.1.0
 3.9.0b4     13.0.0
3.10.0a0     13.0.0

因此,您可能不得不等待更高版本的 Unicode(以及使用该 Unicode 版本的 Python),其中映射比uppercase is "SS" or 1E9E ẞ". 但这实际上可能被Unicode 稳定性政策所排除,该政策部分规定:

如果两个字符在一个 Unicode 版本中形成一个大小写对,则它们将在每个后续版本的 Unicode 中保持一个大小写对。如果两个字符在 Unicode 版本中不形成大小写对,则它们将永远不会在任何后续版本的 Unicode 中形成大小写对。

您可以从一个新引入的角色制作一个案例对,假设您要配对的角色尚未配对,但此处不允许这样做,因为:

  • 这个“新”字符是早在 Unicode 5.1 中引入的;和
  • 我们想要配对的角色已经配对。

我对此的阅读使我相信,在违反该政策的情况下解决此问题的唯一方法是在一个案例对中引入两个新字符,例如:

ß LATIN SMALL LETTER SHARP S THAT IS LOWER OF ẞ
ẞ LATIN CAPITAL LETTER SHARP S THAT IS UPPER OF ß

但是,我不确定这是否会通过 Unicode 联盟的愚蠢过滤器 :-)

为了立即修复,您可以简单地将特定字符强制为您想要的任何字符,然后再应用内置的大小写更改,例如:

to_be_uppered.replace('ß', 'ẞ').upper()
to_be_lowered.replace('ẞ', 'ß').lower()

后者似乎是不必要的,至少在我的版本 Python 3.8.2 上是这样。我包含它以防万一较早的 Python 版本可能需要它。如果事实证明您需要处理更多这样的情况,甚至可能值得将它们放入客户my_upper()和功能中。my_lower()


推荐阅读