Я пытаюсь использовать японский морфологический анализатор MeCab в программе на C # (Visual Studio 2010 Express, Windows 7), и что-то не так с кодировкой.Если мой ввод (вставленный в текстовое поле) будет таким:
一方、広義の「ネコ」は、ネコ類(ネコ科動物)の一部、あるいはその全ての獣を指す包括的名称を指す。
Тогда мой вывод (в другом текстовом поле) будет выглядеть так:
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
( åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
) åè©ž,サ変接続,*,*,*,*,*
? åè©ž,サ変接続,*,*,*,*,*
????????????????????????? åè©ž,サ変接続,*,*,*,*,*
EOS
Я бы предположил, что это текст в некоторыхдругая кодировка ошибочно принимается за текст в кодировке UTF-8.Но если предположить, что это EUC-JP и использовать Encoding.Convert для преобразования его в UTF-8, это не изменит выходных данных;Предполагая, что это Shift-JIS и делая то же самое, мы получаем разную тарабарщину.Кроме того, хотя он определенно обрабатывает текст - именно так должен форматироваться вывод MeCab - он также не интерпретирует ввод как UTF-8.Если бы это было так, в выводе не было бы всех идентичных строк, начинающихся с односимвольных «соединений», которые он явно не мог бы идентифицировать.
Я получаю еще один по-другому выглядящий набор тарабарщиныкогда я запускаю предложение через командную строку MeCab.Но, опять же, это просто ряд одиночных вопросительных знаков и скобок, идущих вниз по левому краю, поэтому проблема не только в том, что командная строка Windows не поддерживает шрифты с японскими символами;опять же, он просто не читает ввод как UTF-8.(Я установил MeCab в режиме 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 is nothandled», и добавив «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);
}
Предложения / насмешки?