//--------------------------------------------------------------------- // 入力文字列の変換を試みる。 public String Trans(String inputstring) { TextScanner scanner = new TextScanner(); // ブラウザからならHTMLとしてscanさせる(タグをまとめる) if (isBrowser) { scanner.htmlText = true; } // inputstringを語のchainに分解する WordChain wc = scanner.Scan(inputstring); if (this.pBar != null) { this.pBar.Maximum = wc.Length * 2; } // 形態素解析 & 翻訳処理 (本格的じゃないよ) KJ_Analyzer analyzer = new KJ_Analyzer(this); wc = analyzer.MorphologicScan(wc); // 翻訳はここ // WordChainから翻訳後文字列を作り出す if (showoriginal) { return(Chain2String_for_Web(wc)); // Web用 } else { return(Chain2String(wc)); } }
//-------------------------------------------------------------------- // 完全一致の辞書検索 (再起にすると時間がかかりすぎるので再起なし) // static public WordChain DividedWordSearch(string str) { WordTable wt; WordChain wc; #if DEBUG_LOG KJ_Analyzer.WriteDebugLog("DividedWordSearch:" + str); #endif SearchResult sResult = KJ_dict.SearchFull(str); if (sResult == null) { // strが辞書にない // wc = WordPartProc(wt); return(null); } wt = new WordTable(str); wc = new WordChain(); // 検索できた wt.SetResult(sResult); // wt3に検索結果を入れる //wt.IsDevided=true; // 分割語であるマーク wc.Add(wt); return(wc); }
// Insert chain // wc( wt2---wt3---wt4 ) // // ----wt1---wt2---wt3---wt4------a----b----c----- // public void Insert(WordTable wt1, WordChain wc) { if (wt1 == null) { this.head = wc.head; this.tail = wc.tail; return; } if (wc == null || wc.head == null) { return; } if (wt1.next == null) { Debug.Assert(this.tail == wt1); wt1.next = wc.head; wc.head.prev = wt1; this.tail = wc.tail; return; } WordTable oldnext = wt1.next; wt1.next = wc.head; wc.head.prev = wt1; wc.tail.next = oldnext; oldnext.prev = wc.tail; }
static public WordChain GetMinimunCostChain(WordChain wc1, WordChain wc2, WordChain wc3) { WordChain min_wc = GetMinimunCostChain(wc1, wc2); return(GetMinimunCostChain(min_wc, wc3)); }
//------------------------------------------------------- // 分割なし完全一致の語 static public WordTable Scan(WordChain wChain, WordTable wTable) { if (wTable.IsTranslated()) { return(wTable); // 変換済みなら何もしない } // 翻訳しなくていい文字は抜ける if (!wTable.IsWord() || // 空白や制御文字 wTable.IsDigit() || wTable.IsOther()) // 記号 { return(wTable); } // 助詞なら抜ける if (wTable.posCategory == PosCategory.PP) { return(wTable); } // 独立した1文字の語は辞書より先に検索 (単独の이など) if (wTable.word.Length == 1) { CheckOneWord(wTable); if (wTable.transWord != "") { return(wTable); // match } } // 全体で完全一致で検索 SearchResult sResult = KJ_dict.SearchFull(wTable.word); if (sResult != null) { wTable.SetResult(sResult); return(wTable); // 完全一致で見つかった } // 4文字語の調査 (部分分割後は使わない) WordChain wc = Check4Chars(wTable); if (wc != null) { wChain.Swap(wTable, wc); return(wc.Tail); } return(wTable); }
//-------------------------------------------------------------- //------------------------------------------------------------------ // 分割も考慮し詳しい(?)解析 // 分解後チェーンの最後のwTableを返す // // // PalDalHan WordTable ←input // ↓ // PalDal WordTable // Han WordTable ←return // private WordTable ScanDetail(WordChain wChain, WordTable wTable) { if (wTable.IsTranslated()) { return(wTable); // 変換済みなら何もしない } #if DEBUG_LOG KJ_Analyzer.WriteDebugLog("ScanDetail"); #endif // 各国固有部 if (KJ_dict.inputIsHangul) { WordTable rtnWt = ScanDetailKr(wChain, wTable); if (rtnWt != null) { return(rtnWt); } } else { WordTable rtnWt = ScanDetailJp(wChain, wTable); if (rtnWt != null) { return(rtnWt); } } // 語分割ありで、熟語をチェック WordTable idiomwt = Idiom.Search2(wChain, wTable); if (idiomwt != null) { // 熟語が解決できた return(idiomwt); } // 語の分解 WordChain devChain = WordDivider(wTable); if (devChain != null) // 分解できた? { if (AcceptableTransWord(wTable, devChain)) // 採用できるか? // 採用できるならwTableを分解したチェーンdevChainで入れ替え { wChain.Swap(wTable, devChain); return(devChain.Tail); // 分解した最後の位置へ } } // それでも変換なしならカタカナまたはハングルに自動変換 wTable = ConvAutoConv(wTable); return(wTable); }
public WordChain Scan(string inputstring) { this.inputString = inputstring; this.stringIndex = 0; WordChain wChain = new WordChain(); WordTable wordT; // inputStringから語のchainを作成する。 while (true) { // inputStringから1語切り出す wordT = PicupWordTable(); if (wordT.word == "") { break; // 取り出せなかったら終了 } wChain.Add(wordT); } // end of while ( PicupWordTable loop ) // 漢字+ひらがな などいくつかの並びはまとめる。 ( wordT merge loop ) CharCategory prevCharCategory = CharCategory.Null; WordTable prevwordT = new WordTable(); wordT = wChain.Head; while (wordT != null) { CharCategory mergedCharCategory; mergedCharCategory = IsMergedable(prevCharCategory, wordT.charCategory); if (mergedCharCategory != CharCategory.Null) { WordTable newWt = new WordTable(prevwordT.word + wordT.word);; newWt.charCategory = mergedCharCategory; newWt.posCategory = PosCategory.Other; wChain.Delete(prevwordT); wChain.Insert(wordT, newWt); wChain.Delete(wordT); wordT = newWt; } prevCharCategory = wordT.charCategory; prevwordT = wordT; wordT = wordT.next; // 次の語へ } // end of while ( wordT merge loop ) return(wChain); }
//------------------------------------------------------------------- // private WordTable ScanDetailKr(WordChain wChain, WordTable wTable) { if (wTable.posCategory == PosCategory.PP) { // PosCategory.PPが設定されているK->J方向なら助詞は翻訳済み。 return(wTable); } return(null); }
static public WordChain GetMinimunCostChain(WordChain wc1, WordChain wc2, WordChain wc3, WordChain wc4) { WordChain min_wc1 = GetMinimunCostChain(wc1, wc2); WordChain min_wc2 = GetMinimunCostChain(wc3, wc4); return(GetMinimunCostChain(min_wc1, min_wc2)); }
//------------------------------------------------------------------- // WordChainの各WordTableから翻訳結果を取り出し翻訳後文字列を返す private String Chain2String(WordChain wc) { StringBuilder result; // 出力文字列 result = new StringBuilder(); // debuginfo is True if (this.debugInfo) { result.Append("original ⇒ result " + "(char)(pos)(GetWordCost)(divided)\n"); } // 語のchainを先頭から舐め、翻訳結果をresultに順次追加。 WordTable wt = wc.Head; while (wt != null) { // debuginfo is True if (this.debugInfo) { if (wt.IsWord()) { result.Append(wt.word + " ⇒ "); } } // 翻訳用前処理 TranslationPreproc(wt); // wtから翻訳済みテキストを取り出す string translated = wt.GetTranslatedText(); // 翻訳できなかったら元文字をそのまま返す if (translated == "") { translated = wt.word; } result.Append(translated); // debuginfo is True if (this.debugInfo) { result.Append("\n"); MakeDebugInfo(result, wt); } // 次のWordTableへ wt = wt.next; } return(result.ToString()); }
//------------------------------------------------------- static private WordChain DivideCountable(WordTable wTable) { // 数詞チェック WordChain wc = DivideCountableMain(wTable, PosCategory.Numeral); if (wc == null) { // 数詞でなかったら、助数詞チェック wc = DivideCountableMain(wTable, PosCategory.Numerative); } return(wc); }
//------------------------------------------------------------------ // 3文字語の調査 (部分分割後も使う) static private WordChain Check3Chars(WordTable wTable) { SearchResult sResult; // ABC ---> AB + C String head = wTable.word.Remove(2, 1); String suffix = wTable.word.Substring(2, 1); sResult = KJ_dict.SearchFull(head); if (sResult != null) { // lastWordListにあるか調べる string translatedSuffix = KJ_Filter.SearchSuffix(suffix); if (translatedSuffix != "") { WordTable headWt = new WordTable(head); headWt.SetResult(sResult); WordChain wc = new WordChain(headWt); WordTable wt = new WordTable(suffix, translatedSuffix); wt.Cost = 5; wc.Add(wt); return(wc); } } // ABC ---> A + BC String prefix = wTable.word.Remove(1, 2); String tail = wTable.word.Substring(1, 2); sResult = KJ_dict.SearchFull(tail); if (sResult != null) { // lastWordListにあるか調べる string translatedPrefix = KJ_Filter.SearchPrefix(prefix); if (translatedPrefix != "") { WordTable wt = new WordTable(prefix, translatedPrefix); wt.Cost = 5; WordChain wc = new WordChain(wt); WordTable tailWt = new WordTable(tail); tailWt.SetResult(sResult); // 全体でmatch wc.Add(tailWt); return(wc); } } return(null); }
//---------------------------------------------------------------- // 語分割ありの熟語チェック // 공부하지는 못할 것이라는==> 공부 + 하지는 못할 것이라는 // ~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ // startwt ここのWordTableはdivided=Trail // static public WordTable Search2(WordChain wc, WordTable startwt) { String str = startwt.word; if (!startwt.IsWord()) { return(null); // 空白などで始まる場合は、は処理しない } int target_len = 1; int str_len = str.Length; // 前から1文字ずつ落としつつ,熟語検索。 while (true) { if (target_len >= str_len) { break; } // 文字列を分割する // str --> str2 + str3 String str2 = str.Substring(0, target_len); String str3 = str.Remove(0, target_len); WordTable wt3 = new WordTable(str3); wt3.next = startwt.next; wt3.prev = startwt.prev; WordTable idiomTable = Idiom.Search(wc, wt3); if (idiomTable != null) { // 熟語確定 WordTable wt2 = new WordTable(str2); wc.InsertBefore(idiomTable, wt2); WordChain wc2 = KJ_Analyzer.WordPartProc(wt2); if (wc2 != null) { wc.Swap(wt2, wc2); } idiomTable.divided = Divided.Trail; return(idiomTable); } target_len++; } return(null); }
//------------------------------------------------------- // 翻訳のメイン // KJ_browserの中にも同じものをコピーで持っている点注意 // public WordChain MorphologicScan(WordChain wChain) { #if DEBUG_LOG KJ_Analyzer.StartDebugLog(); KJ_Analyzer.WriteDebugLog("MorphologicScan"); #endif if (!wChain.Exist()) { return(wChain); } WordTable wTable = wChain.Head; // 解析ループ 1回目 // 翻訳前処理(助詞分離など先に 熟語の精度を上げるため) // 고정 관념을 ---> 고정 관념 을に分離しておくため(熟語判定用) while (wTable != null) { this.sTrans.pBarStep(); // プログレスバーを進める // 1回目処理 wTable = firstScan(wChain, wTable); wTable = wTable.next; // 次の語へ } // 翻訳前処理ここまで // 解析ループ 2回目 (翻訳のメインループ) wTable = wChain.Head; // 再度先頭から while (wTable != null) { this.sTrans.pBarStep(); // プログレスバーを進める // 2回目処理 wTable = secondScan(wChain, wTable); wTable = wTable.next; // 次の語へ } // 翻訳のメインループ ここまで #if DEBUG_LOG KJ_Analyzer.EndDebugLog(); #endif return(wChain); }
//-------------------------------------------------------------------- // wTableを翻訳した結果のチェーンが使えるかどうか? private bool AcceptableTransWord(WordTable wTable, WordChain wChain) { // 3文字以上で、翻訳語の同じチェーンなら不採用 if (wTable.word.Length > 2 && wTable.word.Length == wChain.Length) { return(false); } // 翻訳済み長が全体の3分の1以下なら不採用 if (wChain.TranslatedCharCount() <= wTable.word.Length / 3) { return(false); } return(true); // 採用可 }
// Chainの最後にChainを追加 public void Add(WordChain wc2) { if (wc2 == null) { return; // 何もしない } if (head == null) { this.head = wc2.head; this.tail = wc2.tail; return; } this.tail.next = wc2.head; wc2.head.prev = this.tail; this.tail = wc2.tail; }
static public WordTable Scan(WordChain wChain, WordTable wTable) { if (wTable.IsTranslated()) { return(wTable); // 変換済みなら何もしない } if (KJ_dict.inputIsHangul) { wTable = ScanPPKr(wChain, wTable); } else { wTable = ScanPPJp(wChain, wTable); } return(wTable); }
//------------------------------------------------------- // 語のchainを先頭から舐め、熟語を探す。 static public WordTable Scan(WordChain wChain, WordTable wTable) { // 熟語は優先のため変換済みチェックなし //if(wTable.IsTranslated()){ // return wTable; // 変換済みなら何もしない //} // wtで始まる熟語のチェック WordTable idiomwt = Idiom.Search(wChain, wTable); if (idiomwt != null) { // 熟語が解決できた return(idiomwt); } return(wTable); }
//------------------------------------------------------------------- // チェーンの前処理。 // 句読点の判定、置換など // private WordTable ChainPreProc(WordChain wChain, WordTable wTable) { if (wTable.IsTranslated()) { return(wTable); // 変換済みなら何もしない } if (wTable.charCategory == CharCategory.Letter) { // 一種の正規化 if (wTable.word == "ㆍ") // 0x318D 韓国で使われる中点 { wTable.word = "・"; // 0x30FB 日本語の全角中点 } } if (wTable.charCategory == CharCategory.Punctuation) { if (KJ_dict.inputIsHangul) { if (wTable.word == ".") { if (wTable.next == null || !wTable.next.IsWord()) { wTable.transWord = "。"; } } } else { if (wTable.word == "、") { wTable.transWord = ", "; } if (wTable.word == "。") { wTable.transWord = ". "; } } } return(wTable); }
//-------------------------------------------------------------- public WordTable firstScan(WordChain wChain, WordTable wTable) { // 速度向上のため、skipさせる if (wTable.IsTransSkipWord()) { return(wTable); // 何もせずreturn } // 前処理 wTable = ChainPreProc(wChain, wTable); // 数助詞,冠数詞をチェック wTable = Numerative.Scan(wChain, wTable); // 助詞の解析を試す (前の語の辞書引きあり) wTable = KJ_pp.Scan(wChain, wTable); //2005.08.26 数詞の前に return(wTable); }
//------------------------------------------------------- static private WordChain DivideCountableMain(WordTable wTable, PosCategory poscategory) { WordChain wc = null; StringDivider sd = new StringDivider(wTable.word); // 後から1文字ずつ落としつつ,検索。 string trans = ""; while (sd.eof() == false) { // 文字列を分割する HYAM.KJ_dict.Pair pair = sd.DivideBackward(); if (poscategory == PosCategory.Numeral) { trans = KJ_Filter.SearchNumeral(pair.head); } else { trans = KJ_Filter.SearchNumerative(pair.head); } if (trans != "") { WordTable wt_num = new WordTable(pair.head, trans); wt_num.posCategory = poscategory; wc = new WordChain(wt_num); if (pair.tail != "") { WordTable wt_tail = new WordTable(pair.tail); wc.Add(wt_tail); } return(wc); } } // end of while return(null); }
//-------------------------------------------- // // static public method // static public WordChain GetMinimunCostChain(WordChain wc1, WordChain wc2) { if (wc1 == null) { return(wc2); } if (wc2 == null) { return(wc1); } if (wc1.GetChainCost() < wc2.GetChainCost()) { return(wc1); } else { return(wc2); } }
//------------------------------------------------------------------ private WordChain WordDivider(WordTable wTable) { WordChain wc1 = null; #if DEBUG_LOG KJ_Analyzer.WriteDebugLog("WordDivider"); #endif // 辞書検索なしの助詞チェック if (KJ_dict.inputIsHangul) { wc1 = KJ_pp.CheckPPwithoutDictKr(wTable); } // 3文字の「ハングルまたは漢字」なら特別チェック if (wTable.word.Length == 3 && (CodeCheck.IsHangul(wTable.word) || CodeCheck.IsKanji(wTable.word)) ) { WordChain wcThree = Check3Chars(wTable); if (wcThree != null) { return(wcThree); } } // 全体でmatchしないなら部分文字列で検索(再起 語分解あり) WordChain wc2 = null; wc2 = WordPartProc(wTable); // wtは最後の語テーブル。未変換なら再調査 // WordChain wc3 = CheckLastWord(wChain, wTable); // costが小さい方を採用 WordChain rtnWc = WordChain.GetMinimunCostChain(wc1, wc2); return(rtnWc); }
//-------------------------------------------------------------- public WordTable secondScan(WordChain wChain, WordTable wTable) { // 速度向上のため、skipさせる if (wTable.IsTransSkipWord2()) // 少しゆるいskip { return(wTable); // 何もせずreturn } // 熟語をチェック wTable = Idiom.Scan(wChain, wTable); // 分割なし完全一致の語 wTable = DelimitedWord.Scan(wChain, wTable); // 分割も考慮し詳しい(?)解析 // (辞書引きなし助詞解析あり) // 分解した最後のwTableを返す wTable = ScanDetail(wChain, wTable); return(wTable); }
//------------------------------------------------------------------- // private WordTable ScanDetailJp(WordChain wChain, WordTable wTable) { // 助詞を処理 // (助詞で始まる熟語があるので熟語の後) if (wTable.posCategory == PosCategory.PP) { // 改めて訳語を設定 string pp = KJ_pp.TransJapanesePP(wTable); if (pp != "") { // 訳語設定 wTable.transWord = pp; wTable.Cost = 0; // ハングルの助詞なら、分かち書きのため空白を置く。 wTable.transWord = wTable.transWord + " "; return(wTable); } } return(null); }
//------------------------------------------------------- // 語のchainを先頭から舐め、助詞(Postpositional Particle)を分解する。 static private WordTable ScanPPJp(WordChain wChain, WordTable wTable) { // 語を舐め、助詞を分解する。 if (wTable.IsTranslated() || wTable.IsDigit()) { // 翻訳済み または 数字ならなにもしない。 return(wTable); } // J-->K方向の場合、ハングルは // 前の語に依存するので訳語(ハングル)の設定は別途。 // 助詞である事の確定だけ試みる // 分離されたひらがなの助詞判定だけ PosCategory pp = CheckPos_Hira(wTable.word); if (PosCategory.PP == pp) { wTable.posCategory = pp; } // 漢字+ひらがなの形での助詞分離 if (wTable.charCategory == CharCategory.KanHira) { WordChain resultChain = DivideJapanesePP(wTable); if (resultChain != null) { wChain.Swap(wTable, resultChain); // 前の語は未翻訳なのでそれを返す wTable = resultChain.Head; } } return(wTable); }
//------------------------------------------------------------------ // 4文字語の調査 (部分分割後は使わない) static private WordChain Check4Chars(WordTable wTable) { SearchResult sResult; if (KJ_dict.inputIsHangul) { // 4文字以外は抜ける。 if (wTable.word.Length != 4) { return(null); } if (wTable.word.EndsWith("하게")) { string head = wTable.word.Remove(2, 2); // 4文字なので固定 sResult = KJ_dict.SearchFull(head); if (sResult != null) { WordTable tempwt = new WordTable(head); tempwt.SetResult(sResult); string trans = tempwt.GetTranslatedText(); wTable.transWord = trans + "に"; wTable.Cost = 10; wTable.posCategory = PosCategory.PP; WordChain wc = new WordChain(wTable); // これだけならwtでもいいが、汎用化のためwcで返す return(wc); } } } return(null); }
//---------------------------------------------- // // chain中のwt1を別chainで置き換える // // wc( wt2----------wt3---------wt4 ) // | wc.head wc.tail // v // ----wt1--------a---------b--------c----- // (oldnext) // public void Swap(WordTable wt1, WordChain wc) { Insert(wt1, wc); Delete(wt1); }
//-------------------------------------------------------------- // startwtで始まる熟語を最長一致でチェックする // // (before) // -----wt1-----wt2-----wt3-----wt4-----wt5-----wt6----- // ↑ ↑ // startwt matched // // (after) // -----wt1-----idiomwt-----wt5-----wt6----- // // チェーン中の熟語を成すテーブルは1つにまとめる。 // (正確には熟語のテーブルを挿入し、個々の語のテーブルは削除) // static public WordTable Search(WordChain wc, WordTable startwt) { //熟語は語単位より優先 // if(startwt.IsTranslated()){ // return null; // 翻訳済みの語は触らない // } bool isExist; // 辞書中にチェック対象の語(熟語)が存在するか? WordTable idiomwt = null; // 熟語テーブル SearchResult sResult; string word = startwt.word; // startwtが翻訳済みで助詞なら何もしない // 暫定的 2005.08.26 // if(startwt.IsTranslated() && startwt.pos == PosCategory.PP ){ // return(null); // not found // } // 前方一致で該当なしなら // この語で始まる熟語は辞書にない isExist = KJ_dict.CheckForward(word); if (!isExist) { return(null); // not found } // 前方一致でmatchしたので先読みして熟語チェック String word2 = ""; string next = ""; WordTable nextTable = startwt.next; WordTable matched = startwt; // 次の語以降を足しながらチェック while (nextTable != null) { if (nextTable == null || nextTable.word == "") { break; // 次の語なしなら抜ける } next = nextTable.word; char ch = next[0]; if (Char.IsSeparator(ch)) { next = " "; } if (next == " ") { word = word + next; nextTable = nextTable.next; // 次の語へ continue; // 空白付加だけでは再検索しない } word2 = word + next; //次の語を足して前方一致チェック isExist = KJ_dict.CheckForward(word2); if (!isExist) { // nextを足したら,一致しない。→ これ以上先を見る必要なし break; } // 一致した部分まででで完全一致検索 sResult = KJ_dict.SearchFull(word2); if (sResult != null) { // string trimword = word2; // trimword = trimword.Replace(" ", ""); // 空白削除 if (IsValidIdiom(sResult)) // 長さ4以上でないと採用しない // 熟語が見つかった { idiomwt = new WordTable(word2); idiomwt.charCategory = startwt.charCategory; // 先頭文字種で (混ざっている可能性あるが) idiomwt.posCategory = PosCategory.Idiom; idiomwt.SetResult(sResult); matched = nextTable; // 完全一致した最後のテーブル } } // さらに次の語へ word = word2; // nextを足したものを元とする。 nextTable = nextTable.next; // 次の語へ } // while loop if (startwt.word == word) { // 熟語でなく単なる入力語の完全一致の時は返さない return(null); } if (idiomwt != null) { // 熟語が見つかっている wc.Insert(matched, idiomwt); // startwtからmatchedまでは消していい。 WordTable delwt = startwt; while (true) { wc.Delete(delwt); if (delwt == matched) { break; } delwt = delwt.next; } // 熟語のテーブルを返す return(idiomwt); } // 熟語なし return(null); }
//------------------------------------------------------- // 語のchainを先頭から舐め、助数詞・冠数詞を解析する。 static public WordTable Scan(WordChain wChain, WordTable wTable) { if (wTable.IsTranslated()) { return(wTable); // 変換済みなら何もしない } WordTable next = wTable.NextWord(); // 次の有効な語を返す。(空白skip) // 前後を数字(Digit)に挟まれる場合 if ((wTable.prev != null && wTable.prev.IsDigit()) && (next != null && next.IsDigit())) { string transword = KJ_Filter.SearchNumConnecting(wTable.word); if (transword != "") { wTable.transWord = transword; wTable.posCategory = PosCategory.Numerative; wTable.Cost = 1; return(wTable); } } // 1つ前のWordTableは数字(Digit)の場合 // または数詞(Numeral)である場合 if ((wTable.prev != null && wTable.prev.IsDigit()) || // 800억 の 억 (wTable.PrevWord() != null && wTable.PrevWord().posCategory == PosCategory.Numeral) // 800억원 --> 800+억+원の원 // 160억 개의 のように空白をはさむ事があるので空白skipで前の語を調べる ) { WordChain dividedChain = DivideCountable(wTable); if (dividedChain != null) { // 助数詞であった // devidedChainは 助数詞+語のチェーン。wTableと入れ替える // (+語はない場合もある) wChain.Swap(wTable, dividedChain); // 処理済みTable変更 wTable = dividedChain.Head; } } else { // 次の語が数字である場合 (冠数詞) NumerativePrefix // ★前数字と違い、空白はさんでも許す (약 90만 or 약90만) if (next != null && next.IsDigit()) { string transword = KJ_Filter.SearchPreNum(wTable.word); // string transword = CheckPreNum(wTable); if (transword != "") { wTable.transWord = transword; wTable.posCategory = PosCategory.NumerativePrefix; // ちょっと違うか。あとで wTable.Cost = 1; } } } return(wTable); }