J'essaie d'utiliser l'analyseur morphologique japonais MeCab dans un programme C# (Visual Studio 2010 Express, Windows 7), et quelque chose ne va pas avec l'encodage. Si mon entrée (collé dans une zone de texte) est la suivante:Essayant d'obtenir libmecab.dll (MeCab) pour travailler avec C#
一方、広義の「ネコ」は、ネコ類(ネコ科動物)の一部、あるいはその全ての獣を指す包括的名称を指す。
Puis ma sortie (dans une autre zone de texte) ressemble à ceci:
? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ( åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ) åè©ž,サ変接続,*,*,*,*,* ? åè©ž,サ変接続,*,*,*,*,* ????????????????????????? åè©ž,サ変接続,*,*,*,*,* EOS
Je suppose que c'est le texte dans un autre encodage se tromper pour le texte codé en UTF-8. Mais supposer que c'est EUC-JP et utiliser Encoding.Convert pour le transformer en UTF-8 ne change pas la sortie; en supposant que c'est Shift-JIS et faire la même chose donne un charabia différent. De plus, alors qu'il traite définitivement le texte - c'est ainsi que la sortie de MeCab est censée être formatée - il ne semble pas non plus interpréter l'entrée comme UTF-8. Si c'était le cas, il n'y aurait pas toutes ces lignes identiques dans la sortie commençant par des «composés» à un caractère, qu'il est clairement impossible d'identifier.
Je reçois encore un autre ensemble de charabia quand je lance la phrase à travers la ligne de commande de MeCab. Mais, encore une fois, c'est juste une rangée de simples points d'interrogation et de parenthèses qui descendent à gauche, donc ce n'est pas seulement le problème que la ligne de commande Windows ne supporte pas les polices avec des caractères japonais; encore une fois, il ne lit pas l'entrée en UTF-8. (Je l'ai fait installer MeCab en mode UTF-8.)
Les parties pertinentes du code ressembler à ceci:
[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; }
(En termes de jongler avec des choses plausibles qui cherchent à voir si elles font une différence , J'ai essayé de passer "UnmanagedType.AnsiBStr" à "UnmanagedType.BStr", ce qui donne l'erreur "AccessViolationException n'a pas été gérée", et en ajoutant "CharSet = CharSet.Unicode" aux paramètres DllImport, qui ont transformé la sortie en juste "EOS ".)
Voici comment j'ai fait la conversion:
// 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); }
Suggestions/railleries?
Savez-vous ce que l'encodage de votre dictionnaire est? Essayez de lancer mecab -D et voyez quel jeu de caractères est utilisé. – buruzaemon
Il est configuré pour utiliser le dictionnaire ipadic-utf8. – snarp