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]
,从而生成一个索引器。
。输入将自动获得+“”最后,我不知道怎么做。我不知道怎么做。虽然我还没有检查你的解决方案是否有效(我必须说我不知道什么是映射),但我实际上自己找到了一个解决方案,至少在我看来与你的类似(我将编辑主帖子)正如你在编辑后的帖子中看到的那样,我自己也得出了这个结论,正如我所说的