2012-11-09 53 views
7

我正在使用Assembly C#的Unity项目中工作。我尝试获得像é这样的特殊字符,但在控制台中它只显示一个空白字符:“”。例如翻译“你好吗?”应该返回“CómoEstás?”,但它返回“Cmo Ests”。我将返回字符串“Cmo Ests”放在一个字符数组中,并意识到它是一个非空的空字符。我正在使用Encoding.UTF8,当我这样做时:如何从字符中获取数据

char ch = '\u00e9'; 
print (ch); 

它将打印“é”。我曾尝试使用得到字节关闭一个给定的字符串:“怎么是你”

byte[] utf8bytes = System.Text.Encoding.UTF8.GetBytes(temp); 

平移的同时,它会返回一个字节的字符串,但对于特殊字符,如é,我得到的一系列字节239,191,189,它是一个替换字符。

需要从字符中检索哪些类型的信息才能准确确定它是什么字符?我需要对Google提供给我的信息做些什么,或者是否有其他内容?我需要一个一般情况下,我可以放在我的程序,并将工作任何输入字符串。如果任何人都可以提供帮助,将不胜感激。

这里是引用的代码:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using UnityEngine; 
using System.Collections; 
using System.Net; 
using HtmlAgilityPack; 


public class Dictionary{ 
string[] formatParams; 
HtmlDocument doc; 
string returnString; 
char[] letters; 
public char[] charString; 
public Dictionary(){ 
    formatParams = new string[2]; 
    doc = new HtmlDocument(); 
    returnString = ""; 
} 

public string Translate(String input, String languagePair, Encoding encoding) 
    { 
     formatParams[0]= input; 
     formatParams[1]= languagePair; 
     string url = String.Format("http://www.google.com/translate_t?hl=en&ie=UTF8&text={0}&langpair={1}", formatParams); 

     string result = String.Empty; 

     using (WebClient webClient = new WebClient()) 
     { 
      webClient.Encoding = encoding; 
      result = webClient.DownloadString(url); 
     }  
     doc.LoadHtml(result); 
     input = alter (input); 
     string temp = doc.DocumentNode.SelectSingleNode("//span[@title='"+input+"']").InnerText; 
     charString = temp.ToCharArray(); 
     return temp; 
    } 
// Use this for initialization 
void Start() { 

} 
string alter(string inputString){ 
    returnString = ""; 
    letters = inputString.ToCharArray(); 
    for(int i=0; i<inputString.Length;i++){ 
     if(letters[i]=='\''){ 
      returnString = returnString + "&#39;"; 
     }else{ 
      returnString = returnString + letters[i]; 
     } 
    } 
    return returnString; 
} 
} 
+0

您应该包含生成响应的代码。 –

+0

老实说,我不明白问题所在。我在你的问题中看到的是你正在得到你所要求的。如果你要求UTF8字节,你将得到UTF8字节。 239,191,189是你的单个Unicode字符的UTF8编码。如果您需要从utf8转换为unicode,请执行以下操作:http://stackoverflow.com/questions/11293994/how-to-convert-a-utf-8-string-into-unicode – plinth

+0

您的print() '方法呢?如果您试图将UTF8字节视为字符,则会出现问题。 UTF8字符长度可以超过1个字节。 –

回答

0

实际上,你几乎有它。只需插入带有\ u的编码字母即可。

string mystr = "C\u00f3mo Est\u00e1s?"; 
+0

谢谢,但这是一个案例。我需要有一个通用的解决方案。 –

0

我对GoogleTranslate API了解不多,但我的第一个想法是,你有一个Unicode规范化问题。

看看System.String.Normalize(),它是朋友。

Unicode非常复杂,所以我会简化!许多符号可以以不同的方式用Unicode表示,即:'é'可以表示为'é'(一个字符),或者表示为'e'+'重音字符'(两个字符),或者取决于从API回来,完全是另外一回事。

Normalize函数会将字符串转换为具有相同文本含义的字符串,但可能是不同的二进制值,它可能会修复您的输出问题。

1

也许你应该使用另一个API/URL。下面这个函数使用不同的URL返回JSON数据,似乎更好的工作:

public static string Translate(string input, string fromLanguage, string toLanguage) 
    { 
     using (WebClient webClient = new WebClient()) 
     { 
      string url = string.Format("http://translate.google.com/translate_a/t?client=j&text={0}&sl={1}&tl={2}", Uri.EscapeUriString(input), fromLanguage, toLanguage); 
      string result = webClient.DownloadString(url); 

      // I used JavaScriptSerializer but another JSON parser would work 
      JavaScriptSerializer serializer = new JavaScriptSerializer(); 
      Dictionary<string, object> dic = (Dictionary<string, object>)serializer.DeserializeObject(result); 
      Dictionary<string, object> sentences = (Dictionary<string, object>)((object[])dic["sentences"])[0]; 
      return (string)sentences["trans"]; 
     } 
    } 

如果我在一个控制台应用程序运行以下命令:

Console.WriteLine(Translate("How are you?", "en", "es")); 

它会显示

¿Cómo estás? 
+0

当试图将它放入程序时,它说它缺少名称空间。我试过“使用System.web;”但它仍然表示缺少名称空间。我必须使用什么名称空间才能使其工作? –

+0

您需要将一个程序集引用添加到System.Web.Extensions –

+0

@CameronBarge我已经对Simon的帖子进行了一些编辑(他们正在进行同行评审..),但是一般来说,您需要包含System.Web。扩展程序集(即在“引用”中),并且对System.Net和System.Web.Script.Serialization具有“使用”。 – flindeberg

0

我的项目中有一个同样的问题[语言资源本地化翻译]

I w因为做同样的事情和正在使用.. System.Text.Encoding.UTF8.GetBytes(),并因为utf8编码接收特殊字符,如您的 ,例如结果字符串中的239,191,189。

请看看我的解决方案...希望这有助于

不要使用编码谷歌翻译将返回正确的像á,因为它在字符串中的自我。做一些字符串操作和读取的字符串,因为它是...

通用的解决方案 [作品每一种语言翻译其中谷歌的支持]

try 
{ 
    //Don't use UtF Encoding 
    // use default webclient encoding 

    var url = String.Format("http://www.google.com/translate_t?hl=en&text={0}&langpair={1}", "►" + txtNewResourceValue.Text.Trim() + "◄", "en|" + item.Text.Substring(0, 2));      

    var webClient = new WebClient(); 
    string result = webClient.DownloadString(url); //get all data from google translate in UTF8 coding.. 

     int start = result.IndexOf("id=result_box"); 
     int end = result.IndexOf("id=spell-place-holder"); 
     int length = end - start; 
     result = result.Substring(start, length); 
     result = reverseString(result); 

     start = result.IndexOf(";8669#&");//◄ 
     end = result.IndexOf(";8569#&"); //► 
     length = end - start; 

     result = result.Substring(start +7 , length - 8); 
     objDic2.Text = reverseString(result); 

     //hard code substring; finding the correct translation within the string. 
     dictList.Add(objDic2); 
} 
catch (Exception ex) 
{ 
    lblMessages.InnerHtml = "<strong>Google translate exception occured no resource saved..." + ex.Message + "</strong>"; 
       error = true; 
} 

public static string reverseString(string s) 
{ 
    char[] arr = s.ToCharArray(); 
    Array.Reverse(arr); 
    return new string(arr); 

} 

,你可以从代码中看到没有编码已执行,我发送2个特殊的关键字符作为“►”+ txtNewResourceValue.Text.Trim()+“◄”来确定从谷歌返回翻译的开始和结束。

此外,我检查了我的语言实用工具,我收到“CómoEstás?”。发送 时,如何是你谷歌翻译... :)

问候 [Shaz]

---------------------- -----编辑-------------------------

公共字符串翻译(字符串输入,字符串languagePair) {

try 
    { 


     //Don't use UtF Encoding 
     // use default webclient encoding 
     //input  [string to translate] 
     //Languagepair [eg|es] 

     var url = String.Format("http://www.google.com/translate_t?hl=en&text={0}&langpair={1}", "►" + input.Trim() + "◄", languagePair); 

     var webClient = new WebClient(); 
     string result = webClient.DownloadString(url); //get all data from google translate 

     int start = result.IndexOf("id=result_box"); 
     int end = result.IndexOf("id=spell-place-holder"); 
     int length = end - start; 
     result = result.Substring(start, length); 
     result = reverseString(result); 

     start = result.IndexOf(";8669#&");//◄ 
     end = result.IndexOf(";8569#&"); //► 
     length = end - start; 

     result = result.Substring(start + 7, length - 8); 

     //return transalted string 
     return reverseString(result); 


    } 
    catch (Exception ex) 
    { 
     return "Google translate exception occured no resource saved..." + ex.Message"; 

    } 
} 
+0

谢谢你的回复。你能否提供给我更多的见解,例如,在我的代码中应该去哪里?方法名称和参数。任何帮助,将不胜感激。 –

+0

@Cameron请看看新的编辑代码应该适合你..任何问题,请让我知道... – Shaz

0

你的方法有几个问题。首先,UTF8编码是一种多字节编码。这意味着如果使用任何非ASCII字符(char代码> 127),您将得到一系列特殊字符,它们向系统表明这是一个Unicode字符。所以实际上你的序列239,191,189表示一个不是ASCII字符的单个字符。如果您使用UTF16,那么您将得到固定大小的编码(2字节编码),它实际上将一个字符映射到一个无符号的短符号(0-65535)。

c#中的char类型是一个双字节类型,所以它实际上是一个unsigned short。这与其他语言形成对比,如C/C++,其中char类型是1字节类型。

所以在你的情况下,除非你确实需要使用byte []数组,否则应该使用char []数组。或者,如果要对字符进行编码以便可以在HTML中使用它们,则只需遍历字符并检查字符代码是否大于128,然后就可以用&hex;字符代码替换字符代码。