Python 音译器在某些有向图上失败

Python 音译器在某些有向图上失败,python,cyrillic,Python,Cyrillic,这是我的密码: def digraph(chars): als = "шжяеёющчШЖЯЕЁЮЩЧ" new = {'sh':als[0],'zh':als[1],'ja':als[2],'je':als[3],'jo':als[4], 'ju':als[5],'sx':als[6],'ch':als[7],'Sh':als[8],'Zh':als[9], 'Ja':als[10],'Je':als[11],'Jo':als[12],'Ju':als[13],'S

这是我的密码:

def digraph(chars):
als = "шжяеёющчШЖЯЕЁЮЩЧ"
new = {'sh':als[0],'zh':als[1],'ja':als[2],'je':als[3],'jo':als[4],
       'ju':als[5],'sx':als[6],'ch':als[7],'Sh':als[8],'Zh':als[9],
       'Ja':als[10],'Je':als[11],'Jo':als[12],'Ju':als[13],'Sx':als[14],
       'Ch':als[15],'SH':als[8],'ZH':als[9],'JA':als[10],'JE':als[11],
       'JO':als[12],'JU':als[13],'SX':als[14],'CH':als[15]}
try:
    return new[chars]
except:
    return "[Error]"

def trans_cyr(inp):
cyrillic = "абцдэфгхийклмнопрстувъыьзАБЦДЭФГХИЙКЛМНОПРСТУВЫЗ "
latin = "abcdefghijklmnoprstuv$y'zABCDEFGHIJKLMNOPRSTUVYZ "
digs = ['sh','zh','ja','je','jo','ju','sx','ch','Sh','Zh',
        'Ja','Je','Jo','Ju','Sx','Ch','SH','ZH','JA','JE','JO','JU','SX',
        'CH']
prevc = ""
for e, char in enumerate(inp):
    if(prevc != ""):
        comb = prevc + char
        newdig = digraph(comb)
        if(comb in digs):
            print(newdig, end="")
            prevc = ""
        else:
            pos = latin.index(char)
            posp = latin.index(inp[e - 1])
            if(inp[e-1] in "szjcSZJC"):
                print(cyrillic[posp] + cyrillic[pos], end="")
                prevc = ""
            else:
                prevc=""
                continue
    elif(char not in "szjcSZJC"):
        try:
            pos = latin.index(char)
            print(cyrillic[pos], end="")
        except:
            print(char, end="")
    else:
        prevc = char

while True:
cyrinp = input("\n> ")
trans_cyr(cyrinp)
代码应该将拉丁字母音译为西里尔字母,首先从输入中获取每个字符(如果不是'szjc'或其大写等价物),使用index()函数获取其位置,然后获取与拉丁字母位置相同的西里尔字母等价物。然而,西里尔文中有字母,如Я、г、Ю、Ж、Щ、Ч,它们是有向图(ya、ye、yo、yu、zh、sh、shch(sx)、ch),因此不能仅用一个字符进行音译。因此,我要做的是检查当前字母是否等于“szjcSZJC”中的任何一个,如果它等于,则我不打印它,而是将其命名为prevc,如果与prevc组合的下一个字符在数组“digs”中。一切都很完美,如果我输入'jojajo',它会像它应该的那样打印“ёё”,但是-如果有一个未完成的有向图(c没有h,s没有h,x,z没有h,j没有a,e,u和o),那么下一个有向图就不会被音译。示例:sjo:如果我输入sjo,我的预期输出将是Сё,但我得到的是Сё。我有办法解决这个问题吗

编辑:

我写了这段代码:

while True:
cyrillic = "абцдэфгхийклмнопрстувъыьзАБЦДЭФГХИЙКЛМНОПРСТУВЫЗ "
latin = "abcdefghijklmnoprstuv$y'zABCDEFGHIJKLMNOPRSTUVYZ "
als = "шжяеёющчШЖЯЕЁЮЩЧ"
new = {'sh':als[0],'zh':als[1],'ja':als[2],'je':als[3],'jo':als[4],
       'ju':als[5],'sx':als[6],'ch':als[7],'Sh':als[8],'Zh':als[9],
       'Ja':als[10],'Je':als[11],'Jo':als[12],'Ju':als[13],'Sx':als[14],
       'Ch':als[15],'SH':als[8],'ZH':als[9],'JA':als[10],'JE':als[11],
       'JO':als[12],'JU':als[13],'SX':als[14],'CH':als[15]}
inp = input("\n> ") + " "
digraph = ""
prevc = ""
for e, char in enumerate(inp):
    part_j = "jJ"
    part_v = "aeouAEOU"
    part_z = "zZ"
    part_h = "hH"
    part_s = "sS"
    part_x = "hxHX"
    part_c = "cC"
    if((char in part_j and inp[e+1] in part_v) or (char in part_z and inp[e+1] in part_h) or (char in part_s and inp[e+1] in part_x) or (char in part_c and inp[e+1] in part_h)):
        digraph = "yes"
    else:
        digraph = "no"

    if((char in part_v and inp[e-1] in part_j) or (char in part_h and inp[e-1] in part_z) or (char in part_x and inp[e-1] in part_s) or (char in part_h and inp[e-1] in part_c)):
        comb = inp[e-1] + char
        dig = new[comb]
        print(dig, end="")
    elif(digraph == "yes"):
        prevc = char
    else:
        try:
            print(cyrillic[latin.index(char)],end="")
        except:
            print(char, end="")

它似乎与我选择的正确答案有着相同的逻辑,而且它是有效的:)

为什么不看看szjcSZJC后面的字符,看看它是否属于构成有向图的任何东西(在本例中为o)。如果没有,请将其正常音译,然后转到下一个字母,其中它可以识别有向图“jo”。

为什么不查看szjcSZJC后面的字符,看看它是否属于构成有向图的任何字符(在本例中为o)。如果没有,请正常音译它并转到下一个字母,其中它识别有向图“jo”。

这里有一个解决方案,它使用与您的方法相同的代码逻辑,但写得更清楚

CYRILLIC = u"абцдэфгхийклмнопрстувъыьзАБЦДЭФГХИЙКЛМНОПРСТУВЫЗ "
LATIN = u"abcdefghijklmnoprstuv$y'zABCDEFGHIJKLMNOPRSTUVYZ "

DIGRAPHS = u"шжяеёющчШЖЯЕЁЮЩЧШЖЯЕЁЮЩЧ"
LATIN_DIGRAPHS = [u'sh', u'zh', u'ja', u'je', u'jo', u'ju', u'sx', u'ch',
                  u'Sh', u'Zh', u'Ja', u'Je', u'Jo', u'Ju', u'Sx', u'Ch',
                  u'SH', u'ZH', u'JA', u'JE', u'JO', u'JU', u'SX', u'CH']

MAPPING = dict(zip(list(LATIN) + LATIN_DIGRAPHS, CYRILLIC + DIGRAPHS))
DIGRAPH_FIRST_LETTER = u'szjcSZJC'

def latin_to_cyrillic(word):
    translation = []
    possible_digraph = False

    for letter in word:
        if possible_digraph:
            combination = previous_letter + letter
            if combination in LATIN_DIGRAPHS:
                translation.append(MAPPING[combination])
                possible_digraph = False
            else:
                translation.append(MAPPING[previous_letter])
                if letter in DIGRAPH_FIRST_LETTER:
                    previous_letter = letter
                else:
                    translation.append(letter)
                    possible_digraph = False
        else:
            if letter in DIGRAPH_FIRST_LETTER:
                possible_digraph = True
                previous_letter = letter
            else:
                translation.append(MAPPING[letter])
    if possible_digraph:
        translation.append(MAPPING[previous_letter])
    return ''.join(translation)

print latin_to_cyrillic('sjo')
print latin_to_cyrillic('jojajo')
逻辑如下

  • 对于每个字母,检查前一个字母是否是有向图的开头
  • 如果是,请检查上一个字母和当前字母是否是合法的有向图并进行翻译。如果不是,请将前一个字母翻译为单个字母,并检查当前字母是否为有向图的开头。如果是,则将其存储在缓冲区中,然后继续,否则也将其转换
  • 如果前一个字母不是有向图的开头,请检查当前字母是否是有向图的开头。如果是,将其存储在缓冲区中并移动,否则进行转换

不必在拉丁字母表中查找字母的索引,也不用在西里尔字母表中使用该索引,只需使用字典将一种语言中的每个字母映射到另一种语言即可。只需创建一个包含所有拉丁符号(单数和有向图)的列表,再为西里尔文创建一个列表。您只需确保两者的符号顺序相同
dict(zip(alphabet1,alphabet2))
将为
alphabet1
中的每个字母创建一个映射,映射到
alphabet2
中相同索引的每个字母。这里有一个解决方案,它使用与您的方法相同的代码逻辑,但写得更清楚

CYRILLIC = u"абцдэфгхийклмнопрстувъыьзАБЦДЭФГХИЙКЛМНОПРСТУВЫЗ "
LATIN = u"abcdefghijklmnoprstuv$y'zABCDEFGHIJKLMNOPRSTUVYZ "

DIGRAPHS = u"шжяеёющчШЖЯЕЁЮЩЧШЖЯЕЁЮЩЧ"
LATIN_DIGRAPHS = [u'sh', u'zh', u'ja', u'je', u'jo', u'ju', u'sx', u'ch',
                  u'Sh', u'Zh', u'Ja', u'Je', u'Jo', u'Ju', u'Sx', u'Ch',
                  u'SH', u'ZH', u'JA', u'JE', u'JO', u'JU', u'SX', u'CH']

MAPPING = dict(zip(list(LATIN) + LATIN_DIGRAPHS, CYRILLIC + DIGRAPHS))
DIGRAPH_FIRST_LETTER = u'szjcSZJC'

def latin_to_cyrillic(word):
    translation = []
    possible_digraph = False

    for letter in word:
        if possible_digraph:
            combination = previous_letter + letter
            if combination in LATIN_DIGRAPHS:
                translation.append(MAPPING[combination])
                possible_digraph = False
            else:
                translation.append(MAPPING[previous_letter])
                if letter in DIGRAPH_FIRST_LETTER:
                    previous_letter = letter
                else:
                    translation.append(letter)
                    possible_digraph = False
        else:
            if letter in DIGRAPH_FIRST_LETTER:
                possible_digraph = True
                previous_letter = letter
            else:
                translation.append(MAPPING[letter])
    if possible_digraph:
        translation.append(MAPPING[previous_letter])
    return ''.join(translation)

print latin_to_cyrillic('sjo')
print latin_to_cyrillic('jojajo')
逻辑如下

  • 对于每个字母,检查前一个字母是否是有向图的开头
  • 如果是,请检查上一个字母和当前字母是否是合法的有向图并进行翻译。如果不是,请将前一个字母翻译为单个字母,并检查当前字母是否为有向图的开头。如果是,则将其存储在缓冲区中,然后继续,否则也将其转换
  • 如果前一个字母不是有向图的开头,请检查当前字母是否是有向图的开头。如果是,将其存储在缓冲区中并移动,否则进行转换

不必在拉丁字母表中查找字母的索引,也不用在西里尔字母表中使用该索引,只需使用字典将一种语言中的每个字母映射到另一种语言即可。只需创建一个包含所有拉丁符号(单数和有向图)的列表,再为西里尔文创建一个列表。您只需确保两者的符号顺序相同<代码>dict(邮政编码(字母1,字母2))然后将为
alphabet1
中的每个字母创建一个映射,映射到
alphabet2
中相同索引的每个字母。您只需在匹配之前查看输入中的一个字符,就可以使这一过程变得简单。使用一个dict,只需将一个拉丁字符或两个字符序列映射到西里尔字母。您可以完成此任务使用PCRE正则表达式引擎(
((所有有向图)|(单个字母))++
)和映射表的代码明显减少。对于
sjos
,您的代码将失败,因为最后一个字母是有向图的开头,它将尝试访问
inp[e+1]
,从而产生
索引器。
。输入将自动给出+“”最后,索引器不会被丢弃。在匹配之前,只需查看输入中的一个字符,并使用一个dict将一个拉丁字符或两个字符序列映射到西里尔字母,就可以简化这一过程。使用PCRE regex引擎(
((所有有向图))可以用更少的代码完成这一任务|(单字母)+
)和映射表。对于
sjos
,您的代码将失败,因为最后一个字母是有向图的开头,它将尝试访问
inp[e+1]
,从而生成一个
索引器。
。输入将自动获得+“”最后,我不知道怎么做。我不知道怎么做。虽然我还没有检查你的解决方案是否有效(我必须说我不知道什么是映射),但我实际上自己找到了一个解决方案,至少在我看来与你的类似(我将编辑主帖子)正如你在编辑后的帖子中看到的那样,我自己也得出了这个结论,正如我所说的