C# + yahoo翻訳で、日本語、英語の変換を行う
書いた内容忘れそうなのでここにメモ。
EmacsからYahoo翻訳を使う - しょんぼり技術メモ
を参考にしつつ、c#で似たようなものを作ってみました。
static void Main() { Translate tl = new Translate(); Console.WriteLine(tl.EN2JA("This is a pen.")); Console.WriteLine(tl.JA2EN("これは、ペンです。")); }
結果
これは、ペンです。 This is a pen.
これで、翻訳結果が表示されます。
以下ソース
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.IO; using System.Text.RegularExpressions; using System.Web; namespace csharp { public class Translate { const string INIT_URL = "http://honyaku.yahoo.co.jp/transtext/"; const string BASE_URL = "http://honyaku.yahoo.co.jp/TranslationText"; static readonly Encoding ENC = Encoding.UTF8; static readonly Regex _valReg = new Regex("value=\"([^\"]+)\"", RegexOptions.Compiled); static readonly Regex _transReg = new Regex("\"TranslatedText\":\"([^\"]+)\"", RegexOptions.Compiled); static readonly Regex _utf16Reg = new Regex(@"\\u([0-9a-fA-F]{4})", RegexOptions.Compiled); public string EN2JA(string text) { return Trans(text, TransType.EN2JA); } public string JA2EN(string text) { return Trans(text, TransType.JA2EN); } enum TransType { EN2JA, JA2EN } /// <summary> /// crumbを取得 /// </summary> /// <returns></returns> private string GetTTcrumb() { HttpWebRequest req = (HttpWebRequest)WebRequest.Create(INIT_URL); using (var res = req.GetResponse()) using (var s = res.GetResponseStream()) { StreamReader sr = new StreamReader(s, ENC); string html = sr.ReadToEnd(); //htmlのparseは重そうなのでゴリ押しする var match = _valReg.Match(html, html.IndexOf("id=\"TTcrumb\""), 256); return match.Groups[1].Value; } } private string Trans(string text, TransType tt) { //crumbの取得 string crumb = GetTTcrumb(); //訳 return GetTranslatedText(text, crumb, tt); } private string GetTranslatedText(string origin, string crumb, TransType tt) { HttpWebRequest req = (HttpWebRequest)WebRequest.Create(BASE_URL); req.Method = "POST"; //header req.Referer = INIT_URL; req.ContentType = "application/x-www-form-urlencoded; charset=UTF-8"; //body byte[] body = MakePostBody(origin, crumb, tt); req.ContentLength = body.Length; using (var rs = req.GetRequestStream()) rs.Write(body, 0, body.Length); using (var res = req.GetResponse()) using (var s = res.GetResponseStream()) { StreamReader sr = new StreamReader(s, ENC); string json = sr.ReadToEnd(); //やっぱりjsonのparseも面倒なのでゴリ押しする var matches = _transReg.Matches(json); return string.Join("\n", matches.Cast<Match>() .Select(m => _utf16Reg.Replace(m.Groups[1].Value, new MatchEvaluator(StrToChar))) .ToArray() ); } } //MatchEvaluatorデリゲートメソッド private string StrToChar(System.Text.RegularExpressions.Match m) { //3000 ---> ' ' のように、16進数を元に文字列(UNICODE文字列)に変換する return new string(new char[] { (char)Convert.ToInt16(m.Groups[1].Value, 16) }); } /// <summary> /// postするbodyを作成する /// </summary> /// <param name="tt"></param> /// <param name="crumb"></param> /// <param name="text"></param> /// <returns></returns> private byte[] MakePostBody(string text, string crumb, TransType tt) { Dictionary<string, string> dic = new Dictionary<string, string>(); //アイテムを追加 dic.Add("ieid", tt == TransType.EN2JA ? "en" : "ja"); dic.Add("oeid", tt == TransType.EN2JA ? "ja" : "en"); dic.Add("results", "1000"); dic.Add("formality", "0"); dic.Add("output", "json"); dic.Add("p", HttpUtility.UrlEncode(text)); dic.Add("_crumb", crumb); //"key=value"を&で繋げる string body = string.Join("&", dic.Select(pair => pair.Key + '=' + pair.Value).ToArray()); return ENC.GetBytes(body); } } }
元のライセンスが修正BSDなので、こちらも修正BSDとしておきます。 要するに自己責任でどうぞ。
はてな記法わかんない :p