// MeCab -- Yet Another Part-of-Speech and Morphological Analyzer // // Copyright(C) 2001-2006 Taku Kudo // Copyright(C) 2004-2006 Nippon Telegraph and Telephone Corporation using System; using System.Collections.Generic; using System.Text; using NMeCab.Core; namespace NMeCab { public class MeCabTagger : IDisposable { private readonly Viterbi viterbi = new Viterbi(); private readonly Writer writer = new Writer(); #region Mode /// /// 部分解析モード /// public bool Partial { get { this.ThrowIfDisposed(); return this.viterbi.Partial; } set { this.ThrowIfDisposed(); this.viterbi.Partial = value; } } /// /// ソフト分かち書きの温度パラメータ /// public float Theta { get { this.ThrowIfDisposed(); return this.viterbi.Theta; } set { this.ThrowIfDisposed(); this.viterbi.Theta = value; } } /// /// ラティスレベル(どの程度のラティス情報を解析時に構築するか) /// /// /// 0: 最適解のみが出力可能なレベル (デフォルト, 高速) /// 1: N-best 解が出力可能なレベル (中速) /// 2: ソフトわかち書きが可能なレベル (低速) /// public MeCabLatticeLevel LatticeLevel { get { this.ThrowIfDisposed(); return this.viterbi.LatticeLevel; } set { this.ThrowIfDisposed(); this.viterbi.LatticeLevel = value; } } /// /// 全出力モード /// /// /// true: 全出力 /// false: ベスト解のみ /// public bool AllMorphs { get { this.ThrowIfDisposed(); return this.viterbi.AllMorphs; } set { this.ThrowIfDisposed(); this.viterbi.AllMorphs = value; } } /// /// 解析結果のフォーマット /// public string OutPutFormatType { get { this.ThrowIfDisposed(); return this.writer.OutputFormatType; } set { this.ThrowIfDisposed(); this.writer.OutputFormatType = value; } } #endregion #region Constractor /// /// コンストラクタ /// private MeCabTagger() { } #endregion #region Open/Create /// /// MeCabTaggerを開く /// /// 初期化パラメーター private void Open(MeCabParam param) { this.viterbi.Open(param); this.writer.Open(param); } /// /// MeCabTaggerのインスタンスを生成する /// /// MeCabTaggerのインスタンス public static MeCabTagger Create() { MeCabParam param = new MeCabParam(); param.LoadDicRC(); return MeCabTagger.Create(param); } /// /// MeCabTaggerのインスタンスを生成する /// /// 初期化パラメーター /// MeCabTaggerのインスタンス public static MeCabTagger Create(MeCabParam param) { MeCabTagger tagger = new MeCabTagger(); tagger.Open(param); return tagger; } #endregion #region Parse /// /// 解析を行う /// /// 解析対象の文字列 /// 解析結果の文字列 public unsafe string Parse(string str) { fixed (char* pStr = str) return this.Parse(pStr, str.Length); } /// /// 解析を行う /// /// 解析対象の文字列へのポインタ /// 解析対象の文字列の長さ /// 解析結果の文字列 public unsafe string Parse(char* str, int len) { MeCabNode n = this.ParseToNode(str, len); if (n == null) return null; StringBuilder os = new StringBuilder(); this.writer.Write(os, n); return os.ToString(); } /// /// 解析を行う /// /// 解析対象の文字列 /// 文頭の形態素 public unsafe MeCabNode ParseToNode(string str) { if (str == null) throw new ArgumentNullException("str"); fixed (char* pStr = str) return this.ParseToNode(pStr, str.Length); } /// /// 解析を行う /// /// 解析対象の文字列へのポインタ /// 解析対象の文字列の長さ /// 文頭の形態素 public unsafe MeCabNode ParseToNode(char* str, int len) { this.ThrowIfDisposed(); return this.viterbi.Analyze(str, len); } #endregion #region NBest /// /// 解析を行い結果を確からしいものから順番に取得する /// /// 解析対象の文字列 /// 文頭の形態素を確からしい順に取得するための列挙子 public unsafe IEnumerable ParseNBestToNode(string str) { fixed (char* pStr = str) return this.ParseNBestToNode(pStr, str.Length); } /// /// 解析を行い結果を確からしいものから順番に取得する /// /// 解析対象の文字列へのポインタ /// 文頭の形態素を確からしい順に取得するための列挙子の公開 public unsafe IEnumerable ParseNBestToNode(char* str, int len) { if (this.LatticeLevel == 0) throw new InvalidOperationException("Please set one or more to LatticeLevel."); MeCabNode n = this.ParseToNode(str, len); NBestGenerator nBest = new NBestGenerator(); nBest.Set(n); return nBest.GetEnumerator(); } /// /// ParseのN-Best解出力version /// /// 必要な解析結果の個数 /// 解析対象の文字列 /// 解析結果の文字列 public unsafe string ParseNBest(int n, string str) { fixed (char* pStr = str) return this.ParseNBest(n, pStr, str.Length); } /// /// ParseのN-Best解出力version /// /// 必要な解析結果の個数 /// 解析対象の文字列へのポインタ /// 解析対象の文字列の長さ /// 解析結果の文字列 public unsafe string ParseNBest(int n, char* str, int len) { if (n <= 0) throw new ArgumentOutOfRangeException("n", ""); if (n == 1) return this.Parse(str, len); StringBuilder os = new StringBuilder(); foreach (MeCabNode node in this.ParseNBestToNode(str, len)) { this.writer.Write(os, node); if (--n == 0) break; } return os.ToString(); } #endregion #region Dispose private bool disposed; /// /// 使用中のリソースを開放する /// public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposed) return; if (disposing) { this.viterbi.Dispose(); //Nullチェック不要 } this.disposed = true; } ~MeCabTagger() { this.Dispose(false); } private void ThrowIfDisposed() { if (this.disposed) throw new ObjectDisposedException(this.GetType().FullName); } #endregion } }