with script run open from commands python bash cjk

python - script - Convertir pinyin numerado a pinyin con marcas de tono



python shell commands (5)

¿Existen scripts, bibliotecas o programas que utilicen Python o herramientas BASH (por ejemplo, awk , perl , sed ) que puedan convertir correctamente pinyin numerados (por ejemplo, dian4 nao3) a pinyin UTF-8 con marcas de tono (por ejemplo, diàn nǎo)?

He encontrado los siguientes ejemplos, pero requieren PHP o #C :

También he encontrado varias herramientas en línea, pero no pueden manejar un gran número de conversiones.


Encontré una macro VBA que lo hace en Microsoft Word, en pinyinjoe.com

Tenía un defecto menor que informé y él respondió que él incorporaría mi sugerencia "tan pronto como pueda" Eso fue a principios de enero de 2014; No he tenido ninguna motivación para verificar, ya que ya está en mi copia.


Escribí otra función de Python que hace esto, que no distingue entre mayúsculas y minúsculas y preserva los espacios, la puntuación y otros textos (a menos que haya falsos positivos, por supuesto):

# -*- coding: utf-8 -*- import re pinyinToneMarks = { u''a'': u''āáǎà'', u''e'': u''ēéěè'', u''i'': u''īíǐì'', u''o'': u''ōóǒò'', u''u'': u''ūúǔù'', u''ü'': u''ǖǘǚǜ'', u''A'': u''ĀÁǍÀ'', u''E'': u''ĒÉĚÈ'', u''I'': u''ĪÍǏÌ'', u''O'': u''ŌÓǑÒ'', u''U'': u''ŪÚǓÙ'', u''Ü'': u''ǕǗǙǛ'' } def convertPinyinCallback(m): tone=int(m.group(3))%5 r=m.group(1).replace(u''v'', u''ü'').replace(u''V'', u''Ü'') # for multple vowels, use first one if it is a/e/o, otherwise use second one pos=0 if len(r)>1 and not r[0] in ''aeoAEO'': pos=1 if tone != 0: r=r[0:pos]+pinyinToneMarks[r[pos]][tone-1]+r[pos+1:] return r+m.group(2) def convertPinyin(s): return re.sub(ur''([aeiouüvÜ]{1,3})(n?g?r?)([012345])'', convertPinyinCallback, s, flags=re.IGNORECASE) print convertPinyin(u''Ni3 hao3 ma0?'')


La biblioteca cjklib cubre sus necesidades:

O use el shell de Python:

>>> from cjklib.reading import ReadingFactory >>> f = ReadingFactory() >>> print f.convert(''Bei3jing1'', ''Pinyin'', ''Pinyin'', sourceOptions={''toneMarkType'': ''numbers''}) Běijīng

O simplemente la línea de comando:

$ cjknife -m Bei3jing1 Běijīng

Descargo de responsabilidad: he desarrollado esa biblioteca.


Porté el código de dani_l a Kotlin (el código en java debería ser bastante similar). Va :

import java.util.regex.Pattern val pinyinToneMarks = mapOf( ''a'' to "āáǎà", ''e'' to "ēéěè", ''i'' to "īíǐì", ''o'' to "ōóǒò", ''u'' to "ūúǔù", ''ü'' to "ǖǘǚǜ", ''A'' to "ĀÁǍÀ", ''E'' to "ĒÉĚÈ", ''I'' to "ĪÍǏÌ", ''O'' to "ŌÓǑÒ", ''U'' to "ŪÚǓÙ", ''Ü'' to "ǕǗǙǛ" ) fun toPinyin(asciiPinyin: String) :String { val pattern = Pattern.compile("([aeiouüvÜ]{1,3})(n?g?r?)([012345])")!! val matcher = pattern.matcher(asciiPinyin) val s = StringBuilder() var start = 0 while (matcher.find(start)) { s.append(asciiPinyin, start, matcher.start(1)) val tone = Integer.parseInt(matcher.group(3)!!) % 5 val r = matcher.group(1)!!.replace("v", "ü").replace("V", "Ü") // for multple vowels, use first one if it is a/e/o, otherwise use second one val pos = if (r.length >1 && r[0].toString() !in "aeoAEO") 1 else 0 if (tone != 0) s.append(r, 0, pos).append(pinyinToneMarks[r[pos]]!![tone - 1]).append(r, pos + 1, r.length) else s.append(r) s.append(matcher.group(2)) start = matcher.end(3) } if (start != asciiPinyin.length) s.append(asciiPinyin, start, asciiPinyin.length) return s.toString() } fun test() = print(toPinyin("Ni3 hao3 ma0?"))


Tengo un código de Python 3 que hace esto, y es lo suficientemente pequeño como para poner directamente la respuesta aquí.

PinyinToneMark = { 0: "aoeiuv/u00fc", 1: "/u0101/u014d/u0113/u012b/u016b/u01d6/u01d6", 2: "/u00e1/u00f3/u00e9/u00ed/u00fa/u01d8/u01d8", 3: "/u01ce/u01d2/u011b/u01d0/u01d4/u01da/u01da", 4: "/u00e0/u00f2/u00e8/u00ec/u00f9/u01dc/u01dc", } def decode_pinyin(s): s = s.lower() r = "" t = "" for c in s: if c >= ''a'' and c <= ''z'': t += c elif c == '':'': assert t[-1] == ''u'' t = t[:-1] + "/u00fc" else: if c >= ''0'' and c <= ''5'': tone = int(c) % 5 if tone != 0: m = re.search("[aoeiuv/u00fc]+", t) if m is None: t += c elif len(m.group(0)) == 1: t = t[:m.start(0)] + PinyinToneMark[tone][PinyinToneMark[0].index(m.group(0))] + t[m.end(0):] else: if ''a'' in t: t = t.replace("a", PinyinToneMark[tone][0]) elif ''o'' in t: t = t.replace("o", PinyinToneMark[tone][1]) elif ''e'' in t: t = t.replace("e", PinyinToneMark[tone][2]) elif t.endswith("ui"): t = t.replace("i", PinyinToneMark[tone][3]) elif t.endswith("iu"): t = t.replace("u", PinyinToneMark[tone][4]) else: t += "!" r += t t = "" r += t return r

Esto maneja ü , u: y v , todos los cuales he encontrado. Se necesitarán modificaciones menores para la compatibilidad con Python 2.