如何用 US-ASCII 音译波兰字母表?

How to transliterate Polish alphabet with US-ASCII?

是否有或多或少的标准方法来用原始 ASCII (US-ASCII) 字符音译波兰语字母表?

这个问题可以分解为两个相关且更精确的问题:

  1. 如何仅用 26 个基本拉丁字母表字母音译波兰语字母表中的 32 个字母最大程度地理解 波兰语 reader?
  2. 是否有可逆方法来音译任何包含 US-ASCII 字符的波兰语文本?

我看到大多数波兰语网站只是删除了网址中的变音符号。例如:

Świętosław Milczący    →  Swietoslaw Milczacy
Dzierżykraj Łaźniński  →  Dzierzykraj Lazninski
Józef Soćko            →  Jozef Socko

这几乎是不可逆的,但它是波兰语 readers 最易读的音译吗?

在其他一些情况下,可能会使用更复杂的临时音译,例如Wałęsa → Wawensa。进行后一种转换是否有任何标准规则?

P.S。澄清一下,我对音译规则(如 ł → wę → en)感兴趣,而不是对实现感兴趣。类似于 this table.

广告。 1. 波兰语字母仅由两组字母组成:拉丁字母和带变音符号的拉丁字母。因此音译波兰语字母的唯一方法是去掉最后一组的变音符号,例如:

ą --> a
ć --> c
ż --> z
ź --> z
...

这样最易读的音译。

广告。 2.绝对没有。

您可以将变音符号的存在编码为某种三元数,并将它们存储在纯 ASCII 音译附近以使其可逆。

URL 通常包含一些额外的 ID,即使是这个:48686148/how-to-transliterate-polish-alphabet-with-us-ascii

下面是示例实现:

trans_table = {
    'A': ('A', 0),   'a': ('a', 0),
    'Ą': ('A', 1),   'ą': ('a', 1),
    'B': ('B', 0),   'b': ('b', 0),
    'C': ('C', 0),   'c': ('c', 0),
    'Ć': ('C', 1),   'ć': ('c', 1),
    'D': ('D', 0),   'd': ('d', 0),
    'E': ('E', 0),   'e': ('e', 0),
    'Ę': ('E', 1),   'ę': ('e', 1),
    'F': ('F', 0),   'f': ('f', 0),
    'G': ('G', 0),   'g': ('g', 0),
    'H': ('H', 0),   'h': ('h', 0),
    'I': ('I', 0),   'i': ('i', 0),
    'J': ('J', 0),   'j': ('j', 0),
    'K': ('K', 0),   'k': ('k', 0),
    'L': ('L', 0),   'l': ('l', 0),
    'Ł': ('L', 1),   'ł': ('l', 1),
    'M': ('M', 0),   'm': ('m', 0),
    'N': ('N', 0),   'n': ('n', 0),
    'Ń': ('N', 1),   'ń': ('n', 1),
    'O': ('O', 0),   'o': ('o', 0),
    'Ó': ('O', 1),   'ó': ('o', 1),
    'P': ('P', 0),   'p': ('p', 0),
    'R': ('R', 0),   'r': ('r', 0),
    'S': ('S', 0),   's': ('s', 0),
    'Ś': ('S', 1),   'ś': ('s', 1),
    'T': ('T', 0),   't': ('t', 0),
    'U': ('U', 0),   'u': ('u', 0),
    'W': ('W', 0),   'w': ('w', 0),
    'Y': ('Y', 0),   'y': ('y', 0),
    'Z': ('Z', 0),   'z': ('z', 0),
    'Ź': ('Z', 1),   'ź': ('z', 1),
    'Ż': ('Z', 2),   'ż': ('z', 2),
}



def pol2ascii(text):
    plain = []
    diacritics = []
    for c in text:
        ascii_char, diacritic = trans_table.get(c, (c, 0))
        plain.append(ascii_char)
        diacritics.append(str(diacritic))

    return ''.join(plain) + '_' + hex(int('1' + ''.join(reversed(diacritics)), 3))[2:]

reverse_trans_table = {
    k: v for v, k in trans_table.items()
}

def ascii2pol(text):
    plain, diacritics = text.rsplit('_', 1)
    diacritics = int(diacritics, base=16)
    res = []

    for c in plain:
        diacritic = diacritics % 3
        diacritics = diacritics // 3
        pol_char = reverse_trans_table.get((c, diacritic), c)
        res.append(pol_char)

    return ''.join(res)


TESTS = '''
Świętosław Milczący
Dzierżykraj Łaźniński
Józef Soćko
'''

for l in TESTS.strip().splitlines():
    plain = pol2ascii(l)
    original = ascii2pol(plain)
    print(original, plain)
    assert original == l