這篇文章主要介紹了nodejs簡單實現中英文翻譯的方法和示例,雖然還存在著不小的問題,但是也算是基本能用了,這裡推薦給大家。
幫以前同事解決一個需求,中文項目 翻譯 英文項目~~~
考慮到具體實現方面的問題,如果智能的話,肯定是要做中文的語法分析,不過感覺這個有難度。
所以最後的方案是遍歷文件,將中文短語匹配出來,再進行人工翻譯,將中文短語替換成翻譯的內容。當然後期還是需要人工再檢驗下,畢竟代碼中的中文,可能會影響到相關的程序。
這個問題,明顯涉及到 多線程,文件讀寫,第一時間就想到的是 nodejs,雖然nodejs是一個主線程,但是異步文件讀寫,事件響應機制,肯定也是調用了線程,在實際編程的時候不需要考慮線程的相關的問題。
代碼不復雜如下,寫完了之後,適當的封裝了下
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 var fs = require('fs'); var http = require('http'); var filePath = 'D:WORK_new'; var logPath = 'D:chinese.log'; var map = {}; var num = 0; var dictionary = (function () { var map = {}; return { logPath: 'D:chinese.log', set: function (key, val) { map[key] = val || ''; }, get: function (key) { return map[key]||''; }, save2File: function () { fs.writeFile(this.logPath, JSON.stringify(map).replace(/","/g,'",rn"'),{encoding:'utf8',flag:'w'}, function (err) { if (err) throw err; }); }, loadFile: function (callback) { fs.readFile(this.logPath, {encoding:'utf8'},function (err, data) { map = JSON.parse(data); callback(); }) }, translateByGoogle: function (callback) { var index = 0; for (var key in map) { if (map[key] == '') { index++; (function (key) { http.get("http://translate.google.cn/translate_a/t?client=t&hl=zh-CN&sl=zh-CN&tl=en&ie=UTF-8&oe=UTF-8&oc=2&otf=1&ssel=3&tsel=6&sc=2&q="+key, function(res) { res.setEncoding('utf8'); var body = ""; res.on('data', function (chunk) { body+=chunk; }).on('end', function (){ var obj = eval('('+body+')'); map[key] = obj[0][0][0]; index--; if (index == 0) { callback(); } }); }).on('error', function(e) { console.log('http error'); index--; if (index == 0) { callback(); } console.log("Got error: " + e.message); }); })(key); } } } } })(); function File () { var index = 0; var _readFile = function (pathStr, fileBack, doneBack) { fs.readFile(pathStr,{encoding:'utf8'}, function (err, data) { index--; if (err) { data = ""; console.log(err,pathStr) //throw err; } fileBack(data,pathStr); if (index == 0) { doneBack(); } }); }; var _walkDir = function (pathStr, fileBack, doneBack) { fs.readdir(pathStr, function (err, files) { files.forEach(function (file) { if(fs.statSync(pathStr + '/' + file).isDirectory()){ _walkDir(pathStr + '/' + file, fileBack, doneBack); } else { if (/.js$|.html$|.htm$|.jsp$/.test(file)){ index ++; _readFile(pathStr + '/' + file, fileBack, doneBack); } return; } }); }); } this.walkDir = function (pathStr, fileBack, doneBack) { index = 0; _walkDir(pathStr, fileBack, doneBack); } } //第一步 獲取中文 dictionary.logPath = logPath; new File().walkDir(filePath, function (data) { if (!!data) { var match = data.match(/[u4e00-u9faf]+/g); if (!!match) { match.forEach(function (mat) { dictionary.set(mat); }) } } }, function () { console.log('獲取中文 OK'); dictionary.save2File(); }) //第二步 google翻譯 /* dictionary.loadFile(function () { dictionary.translateByGoogle(function () { dictionary.save2File(); }) }); */ //第三步 中文替換 /* dictionary.loadFile(function () { new File().walkDir(filePath, function (data,pathStr) { fs.writeFile(pathStr, data.replace(/[u4e00-u9faf]+/g, function (ch) { return dictionary.get(ch); }),{encoding:'ascii',flag:'w'}, function (err) { if (err) throw err; }); }, function () { console.log('中文替換 OK'); }) }); */問題還是有的
1.nodejs編碼問題,在window環境下對GBK編碼支持不好,主要是utf8文件的處理
2.效率上面可能可以再通過 線程進行優化,這塊沒做深入的考慮
3.匹配出來,可能有單個的標點符號的短語等情況,需要人工排查
實際情況中,文件是GBK的,還有些文件是utf8的,後來還是考慮通過 腳本語言 快手實現的時候,
1.文件編碼的問題,判斷通過搜索
判斷文件首位3個字節是不是 ef bb bf,但是這個只是針對有BOM的utf8格式
對無BOM的utf8格式,需要進行字節特征碼的判斷(有難度,精力有限,使用了上面的方案,對於無BOM的情況,進行人工排查)。
2.因為快手多線程方便編程很簡單,一直以為多線程肯定比單線程效率要好。實際情況卻和想的不一樣,單線程的比多線程的快多了。看來主要瓶頸還是在讀寫文件IO上面。
以上所述就是本文全部內容了,希望大家能夠喜歡。