我试图在C#程序(Visual Studio 2010 Express,Windows 7)中使用日语形态分析器MeCab,并且出现了编码错误。如果我的输入(粘贴到文本框)是这样的:试图让libmecab.dll(MeCab)与C一起工作#
一方、広義の「ネコ」は、ネコ類(ネコ科動物)の一部、あるいはその全ての獣を指す包括的名称を指す。
然后我输出(在另一个文本)看起来是这样的:
? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ( åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ) åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ????????????????????????? åè©ž,サ変接続,*,*,*,*,* EOS
我猜想,这是在其他一些编码是错误的文字用于UTF-8编码的文本。但假设它是EUC-JP并使用Encoding.Convert将它变成UTF-8不会改变输出;假设它是Shift-JIS,并且执行相同的操作会产生不同的乱码。另外,尽管它确实处理文本 - 这就是MeCab输出如何格式化 - 但它似乎并没有将输入解释为UTF-8。如果这样做的话,输出中不会出现所有那些以单字符“化合物”开始的相同行,而这显然无法识别。
当我通过MeCab的命令行运行这个句子时,我又得到了另外一个不同寻常的乱码。但是,再一次,它只是一排单个问号和左边的括号,所以这不仅仅是Windows命令行不支持带有日文字符的字体的问题;再一次,它只是没有以UTF-8格式读取输入内容。 (我没有在UTF-8模式下安装仲裁处)。
代码的相关部分是这样的:
[DllImport("libmecab.dll", CallingConvention = CallingConvention.Cdecl)] private extern static IntPtr mecab_new2(string arg); [DllImport("libmecab.dll", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.AnsiBStr)] private extern static string mecab_sparse_tostr(IntPtr m, string str); [DllImport("libmecab.dll", CallingConvention = CallingConvention.Cdecl)] private extern static void mecab_destroy(IntPtr m); private string meCabParse(string jpnText) { IntPtr mecab = mecab_new2(""); string parsedText = mecab_sparse_tostr(mecab, jpnText); mecab_destroy(mecab); return parsedText; }
(与合理的前瞻性的东西摆弄方面,看看他们是否有所作为,我尝试将“UnmanagedType.AnsiBStr”切换为“UnmanagedType.BStr”,它给出错误“AccessViolationException was unhandled”,并将“CharSet = CharSet.Unicode”添加到DllImport参数中,这会将输出转换为“EOS “)
这就是我一直在做的转换:
// 65001 = UTF-8 codepage, 20932 = EUC-JP codepage private string convertEncoding(string sourceString, int sourceCodepage, int targetCodepage) { Encoding sourceEncoding = Encoding.GetEncoding(sourceCodepage); Encoding targetEncoding = Encoding.GetEncoding(targetCodepage); // convert source string into byte array byte[] sourceBytes = sourceEncoding.GetBytes(sourceString); // convert those bytes into target encoding byte[] targetBytes = Encoding.Convert(sourceEncoding, targetEncoding, sourceBytes); // byte array to char array char[] targetChars = new char[targetEncoding.GetCharCount(targetBytes, 0, targetBytes.Length)]; //char array to targt-encoded string targetEncoding.GetChars(targetBytes, 0, targetBytes.Length, targetChars, 0); string targetString = new string(targetChars); return targetString; } private string meCabParse(string jpnText) { // convert the text from the string from UTF-8 to EUC-JP jpnText = convertEncoding(jpnText, 65001, 20932); IntPtr mecab = mecab_new2(""); string parsedText = mecab_sparse_tostr(mecab, jpnText); // annnd convert back to UTF-8 parsedText = convertEncoding(parsedText, 20932, 65001); mecab_destroy(mecab); }
建议/嘲讽?
你知道什么编码的字典?尝试运行mecab -D并查看正在使用的字符集。 – buruzaemon 2011-06-16 03:23:20
它设置为使用ipadic-utf8字典。 – snarp 2011-06-18 03:43:34