刚开发了一个小程序。
把日文的假名(平假名和片假名)翻译成它对应的罗马字母表示。
这样对于不知道日文假名怎么读的人来说,是一个方便的工具。
using Kana.Properties;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Kana
{
public partial class FormDict : Form
{
protected const string HiraganaType = "hiragana";
protected const string KatakanaType = "katakana";
protected const string Sharp = "#";
protected const string TranslationRegExp = @"(.*)\((.+)\)";
protected const char RomaSplitter = '/';
protected Dictionary<string, (string,string)> KanasToRomasDict = new Dictionary<string, (string, string)>();
protected Dictionary<string, string> RomasToHiraganasDict = new Dictionary<string, string>();
protected Dictionary<string, string> RomasToKatakanasDict = new Dictionary<string, string>();
public FormDict()
{
InitializeComponent();
}
private void FormDict_Load(object sender, EventArgs e)
{
this.LoadTranslations();
this.textBoxRoma.Text = "a";
}
protected virtual void LoadTranslations()
{
Regex reg = new Regex(TranslationRegExp);
using (TextReader reader = new StringReader(Resources.Kana))
{
string type = HiraganaType;
string line = null;
while((line = reader.ReadLine()) != null)
{
line = line.Trim();
if (line.Length == 0)
{
continue;
}
else if (line.StartsWith(Sharp))
{
//#hiragana
//#katakana
type = line.Substring(Sharp.Length).Trim();
continue;
}
else
{
string[] parts = reg.Split(line);
if (parts != null && parts.Length == 4 && parts[0] == string.Empty && parts[parts.Length - 1] == string.Empty)
{
string kana = parts[1];
string roma = parts[2];
string roma1 = roma;
string roma2 = string.Empty;
if (roma.IndexOf(RomaSplitter)>=0)
{
string[] rs = roma.Split(RomaSplitter);
if(rs!=null && rs.Length == 2)
{
roma1 = rs[0];
roma2 = rs[1];
}
}
if (!string.IsNullOrEmpty(kana))
{
this.KanasToRomasDict[kana] = (roma1,roma2);
}
if (!string.IsNullOrEmpty(roma))
{
if (type == HiraganaType)
{
this.RomasToHiraganasDict[roma1] = kana;
if (!string.IsNullOrEmpty(roma2))
{
this.RomasToHiraganasDict[roma2] = kana;
}
}
else if (type == KatakanaType)
{
this.RomasToKatakanasDict[roma1] = kana;
if (!string.IsNullOrEmpty(roma2))
{
this.RomasToKatakanasDict[roma2] = kana;
}
}
}
}
}
}
}
}
private void TextBoxKana_TextChanged(object sender, EventArgs e)
{
this.textBoxRoma.Text = this.KanaToRoma(this.textBoxKana.Text);
}
protected virtual string KanaToRoma(string kanas)
{
List<string> romas = new List<string>();
if (!string.IsNullOrEmpty(kanas))
{
for(int i = 0; i < kanas.Length; i++)
{
string kana = kanas.Substring(i, (i< kanas.Length - 1) ? 2 : 1);
if (this.KanasToRomasDict.TryGetValue(kana, out (string roma1, string roma2) roma))
{
romas.Add(roma.roma1);
i++;
}
else if (this.KanasToRomasDict.TryGetValue(kana.Substring(0, 1), out roma))
{
romas.Add(roma.roma1);
}
}
}
return string.Join(" ", romas);
}
private void TextBoxRoma_TextChanged(object sender, EventArgs e)
{
this.textBoxKana.TextChanged -= this.TextBoxKana_TextChanged;
this.textBoxKana.Text = this.RomaToKana(this.textBoxRoma.Text, this.checkBoxKatakana.Checked);
this.textBoxKana.TextChanged += this.TextBoxKana_TextChanged;
}
protected virtual string RomaToKana(string roma, bool katakana)
{
string[] parts = (roma ?? string.Empty).Split(' ');
if (parts != null && parts.Length > 0)
{
StringBuilder kanas = new StringBuilder();
foreach (string part in parts)
{
if (katakana)
{
if (this.RomasToKatakanasDict.TryGetValue(part, out string kana))
{
kanas.Append(kana);
}
}
else
{
if (this.RomasToHiraganasDict.TryGetValue(part, out string kana))
{
kanas.Append(kana);
}
}
}
return kanas.ToString();
}
return string.Empty;
}
private void ButtonCopyKana_Click(object sender, EventArgs e)
{
Clipboard.SetText(this.textBoxKana.Text);
}
private void ButtonPasteKana_Click(object sender, EventArgs e)
{
this.textBoxKana.Text += Clipboard.GetText();
}
private void ButtonCopyRoma_Click(object sender, EventArgs e)
{
Clipboard.SetText(this.textBoxRoma.Text);
}
private void ButtonPasteRoma_Click(object sender, EventArgs e)
{
this.textBoxRoma.Text += Clipboard.GetText();
}
private void CheckBoxKatakana_CheckedChanged(object sender, EventArgs e)
{
this.textBoxKana.Text = this.RomaToKana(this.textBoxRoma.Text, this.checkBoxKatakana.Checked);
}
}
}
#hiragana
あ(a)
い(i)
う(u)
え(e)
お(o)
か(ka)
き(ki)
く(ku)
け(ke)
こ(ko)
さ(sa)
し(shi)
す(su)
せ(se)
そ(so)
た(ta)
ち(chi)
つ(tsu)
て(te)
と(to)
な(na)
に(ni)
ぬ(nu)
ね(ne)
の(no)
は(ha)
ひ(hi)
ふ(fu)
へ(he)
ほ(ho)
ま(ma)
み(mi)
む(mu)
め(me)
も(mo)
や(ya)
ゆ(yu)
よ(yo)
ら(ra)
り(ri)
る(ru)
れ(re)
ろ(ro)
わ(wa)
を(wo)
ん(n)
が(ga)
ぎ(gi)
ぐ(gu)
げ(ge)
ご(go)
ざ(za)
じ(ji)
ず(zu)
ぜ(ze)
ぞ(zo)
だ(da)
ぢ(ji)
づ(zu)
で(de)
ど(do)
ば(ba)
び(bi)
ぶ(bu)
べ(be)
ぼ(bo)
ぱ(pa)
ぴ(pi)
ぷ(pu)
ぺ(pe)
ぽ(po)
きゃ(kya)
きゅ(kyu)
きょ(kyo)
ぎゃ(gya)
ぎゅ(gyu)
ぎょ(gyo)
しゃ(sya)
しゅ(syu)
しょ(syo)
じゃ(ja)
じゅ(ju)
じょ(jo)
ちゃ(cha)
ちゅ(chu)
ちょ(cho)
にゃ(nya)
にゅ(nyu)
にょ(nyo)
ひゃ(hya)
ひゅ(hyu)
ひょ(hyo)
びゃ(bya)
びゅ(byu)
びょ(byo)
ぴゃ(pya)
ぴゅ(pyu)
ぴょ(pyo)
みゃ(mya)
みゅ(myu)
みょ(myo)
りゃ(rya)
りゅ(ryu)
りょ(ryo)
#katakana
ア(a)
イ(i)
ウ(u)
エ(e)
オ(o)
カ(ka)
キ(ki)
ク(ku)
ケ(ke)
コ(ko)
サ(sa)
シ(shi)
ス(su)
セ(se)
ソ(so)
タ(ta)
チ(chi)
ツ(tsu)
テ(te)
ト(to)
ナ(na)
ニ(ni)
ヌ(nu)
ネ(ne)
ノ(no)
ハ(ha)
ヒ(hi)
フ(fu)
ヘ(he)
ホ(ho)
マ(ma)
ミ(mi)
ム(mu)
メ(me)
モ(mo)
ヤ(ya)
イ(i)
ユ(yu)
ェ(e)
ヨ(yo)
ラ(ra)
リ(ri)
ル(ru)
レ(re)
ロ(ro)
ワ(wa)
ウィ(wi)
ウ(u)
ウェ(we)
ヲ(wo/o)
ン(n)
ガ(ga)
ギ(gi)
グ(gu)
ゲ(ge)
ゴ(go)
ザ(za)
ジ(ji)
ズ(zu)
ゼ(ze)
ゾ(zo)
ダ(da)
ヂ(dji)
ヅ(dzu)
デ(de)
ド(do)
バ(ba)
ビ(bi)
ブ(bu)
ベ(be)
ボ(bo)
パ(pa)
ピ(pi)
プ(pu)
ペ(pe)
ポ(po)
キャ(kya)
キュ(kyu)
キョ(kyo)
ギャ(gya)
ギュ(gyu)
ギョ(gyo)
シャ(sha)
シュ(shu)
ショ(sho)
ジャ(ja)
ジュ(ju)
ジョ(jo)
チャ(cha)
チュ(chu)
チョ(cho)
ヂャ(dha)
ヂュ(dhu)
ヂョ(dho)
ニャ(nya)
ニュ(nyu)
ニョ(nyo)
ヒャ(hya)
ヒュ(hyu)
ヒョ(hyo)
ビャ(bya)
ビュ(byu)
ビョ(byo)
ピャ(pya)
ピュ(pyu)
ピョ(pyo)
ミャ(mya)
ミュ(myu)
ミョ(myo)
リャ(rya)
リュ(ryu)
リョ(ryo)
ヴャ(vya)
ヴュ(vyu)
ヴョ(vyo)