public void NumberTest() { Assert.AreEqual( "25", StringNormalizer.NormalizeText( "二十五", NormalizeTextOption.Number | NormalizeTextOption.KanjiDigit)); Assert.AreEqual( "34000612", StringNormalizer.NormalizeText( "三千四百万六百十二", NormalizeTextOption.Number | NormalizeTextOption.KanjiDigit)); Assert.AreEqual( "34124612", StringNormalizer.NormalizeText( "三千四百十2万四千六百十二", NormalizeTextOption.Number | NormalizeTextOption.KanjiDigit)); Assert.AreEqual( "1209", StringNormalizer.NormalizeText( "1209", NormalizeTextOption.Number | NormalizeTextOption.KanjiDigit)); Assert.AreEqual( "21000005", StringNormalizer.NormalizeText( "②千百万Ⅴ", NormalizeTextOption.Number | NormalizeTextOption.KanjiDigit)); Assert.AreEqual( "1000000051100", StringNormalizer.NormalizeText( "億510千100", NormalizeTextOption.Number | NormalizeTextOption.KanjiDigit)); //StringNormalizer.NormalizeText("1209ィぅェガABCdefdefAA十二"); }
/// <summary> /// 棋力を解析します。 /// </summary> /// <remarks> /// <paramref name="text"/>に棋力を表す文字列が含まれていれば /// 棋力として認定することにします。 /// (さすらいの12級 とかもあり) /// </remarks> public static SkillLevel ParseSkillLevel(string text) { if (string.IsNullOrEmpty(text)) { return(null); } var skillLevel = new SkillLevel() { OriginalText = text.Trim() }; var normalized = StringNormalizer.NormalizeText(text); var index = 0; while (true) { // マッチする文字列がある間、棋力の検索をします。 var m = SkillLevelRegex.Match(normalized, index); if (!m.Success) { break; } // 棋力の解析を行います。 var n10 = GetNumber(m.Groups[1].Value); var n1 = GetNumber(m.Groups[2].Value); if (n1 == null) { index = m.Index + m.Length; continue; } var skillKind = GetSkillKind(m.Groups[3].Value); if (skillKind == SkillKind.Unknown) { index = m.Index + m.Length; continue; } // プレイヤーの棋力を設定します。 skillLevel.Kind = skillKind; skillLevel.Grade = ((n10 != null ? n10.Value : 0) * 10 + n1.Value); return(skillLevel); } // 棋力不明で登録時の文字列だけ保持します。 return(skillLevel); }
/// <summary> /// 差し手のパースを行います。 /// </summary> public static Move ParseMoveEx(string text, bool isNeedEnd, bool isNormalizeText, ref string parsedText) { if (string.IsNullOrEmpty(text)) { return(null); } var move = new Move() { OriginalText = text.Trim(), }; // 文字列を正規化します。 if (isNormalizeText) { text = StringNormalizer.NormalizeText( text, NormalizeTextOption.All & ~NormalizeTextOption.KanjiDigit); } // 投了などの特殊な指し手の判断を行います。 var m = SpecialMoveRegex.Match(text); if (m.Success) { // 手番が指定されていればそれを取得します。 move.BWType = GetBWType(m.Groups[3].Value); // 投了などの指し手の種類を取得します。 var smoveType = GetSpecialMoveType(m.Groups[4].Value); if (smoveType == SpecialMoveType.None) { return(null); } move.SpecialMoveType = smoveType; } else { m = MoveRegex.Match(text); if (!m.Success) { return(null); } // 手番が指定されていれば、それを取得します。 move.BWType = GetBWType(m.Groups[1].Value); // 33同銀などを有効にします。 // 筋・段 var file = GetNumber(m.Groups[2].Value); var rank = GetNumber(m.Groups[3].Value); // 「同~」であるかどうかを特定します。 // 3同銀などの指し手を受理しないように、数字があれば、 // ちゃんと二つとも設定されているか調べます。 move.SameAsOld = m.Groups[4].Success; if (!move.SameAsOld || file != null || rank != null) { // 筋 if (file == null) { return(null); } move.File = file.Value; // 段 if (rank == null) { return(null); } move.Rank = rank.Value; } // 駒の種類 var piece = GetPiece(m.Groups[5].Value); if (piece == null) { return(null); } move.Piece = piece; // 相対位置 move.RelFileType = GetRelFileType(m.Groups[6].Value); // 駒の移動の種類 move.RankMoveType = GetRankMoveType(m.Groups[7].Value); // 駒打ちなどのアクション move.ActionType = GetActionType(m.Groups[8].Value); // 移動前の位置 if (m.Groups[9].Success) { move.SrcSquare = new Square( int.Parse(m.Groups[10].Value), int.Parse(m.Groups[11].Value)); } } // 解析文字列が正しく終わっているか調べます。 if (isNeedEnd && (m.Length < text.Length && !char.IsWhiteSpace(text[m.Length]))) { return(null); } if (!move.Validate()) { return(null); } parsedText = m.Value; return(move); }