public override ParseResult Parse(ExtractResult extResult)
        {
            // check if the parser is configured to support specific types
            if (SupportedTypes != null && !SupportedTypes.Any(t => extResult.Type.Equals(t)))
            {
                return(null);
            }

            string      extra = null;
            ParseResult ret   = null;

            extra = extResult.Data as string;

            var getExtResult = new ExtractResult()
            {
                Start  = extResult.Start,
                Length = extResult.Length,
                Data   = extResult.Data,
                Text   = extResult.Text,
                Type   = extResult.Type
            };

            if (Config.CultureInfo.Name == "zh-CN")
            {
                getExtResult.Text = ReplaceTraWithSim(getExtResult.Text);
            }

            if (extra == null)
            {
                return(null);
            }
            if (extra.Contains("Integer"))
            {
                ret = ParseInteger(getExtResult);
            }
            else if (extra.Contains("Per"))
            {
                ret = ParsePercentage(getExtResult);
            }
            else if (extra.Contains("Num"))
            {
                getExtResult.Text = NormalizeCharWidth(getExtResult.Text);
                ret = DigitNumberParse(getExtResult);
                if (Config.NegativeNumberSignRegex.IsMatch(getExtResult.Text) && (double)ret.Value > 0)
                {
                    ret.Value = -(double)ret.Value;
                }
                ret.ResolutionStr = ret.Value.ToString();
            }
            else if (extra.Contains("Pow"))
            {
                getExtResult.Text = NormalizeCharWidth(getExtResult.Text);
                ret = PowerNumberParse(getExtResult);
                ret.ResolutionStr = ret.Value.ToString();
            }
            else if (extra.Contains("Frac"))
            {
                ret = ParseFraction(getExtResult);
            }
            else if (extra.Contains("Dou"))
            {
                ret = ParseDouble(getExtResult);
            }

            else if (extra.Contains("Ordinal"))
            {
                ret = ParseOrdinal(getExtResult);
            }

            if (ret != null)
            {
                ret.Text = extResult.Text;
            }

            return(ret);
        }
        // Parse percentage phrase.
        protected ParseResult ParsePercentage(ExtractResult extResult)
        {
            var result = new ParseResult
            {
                Start  = extResult.Start,
                Length = extResult.Length,
                Text   = extResult.Text,
                Type   = extResult.Type
            };

            var  resultText = extResult.Text;
            long power      = 1;

            if (extResult.Data.ToString().Contains("Spe"))
            {
                resultText = NormalizeCharWidth(resultText);
                resultText = ReplaceUnit(resultText);

                if (resultText == "半額" || resultText == "半値" || resultText == "半折")
                {
                    result.Value = 50;
                }
                else if (resultText == "10成" || resultText == "10割" || resultText == "十割")
                {
                    result.Value = 100;
                }
                else
                {
                    var    matches = Config.SpeGetNumberRegex.Matches(resultText);
                    double intNumber;

                    if (matches.Count == 2)
                    {
                        var intNumberChar = matches[0].Value[0];

                        if (intNumberChar == '対' || intNumberChar == '对')
                        {
                            intNumber = 5;
                        }
                        else if (intNumberChar == '十' || intNumberChar == '拾')
                        {
                            intNumber = 10;
                        }
                        else
                        {
                            intNumber = Config.ZeroToNineMap[intNumberChar];
                        }

                        var    pointNumberChar = matches[1].Value[0];
                        double pointNumber;
                        if (pointNumberChar == '半')
                        {
                            pointNumber = 0.5;
                        }
                        else
                        {
                            pointNumber = Config.ZeroToNineMap[pointNumberChar] * 0.1;
                        }

                        result.Value = (intNumber + pointNumber) * 10;
                    }
                    else if (matches.Count == 5)
                    {
                        // Deal the Japanese percentage case like "xxx割xxx分xxx厘", get the integer value and convert into result.
                        var intNumberChar   = matches[0].Value[0];
                        var pointNumberChar = matches[1].Value[0];
                        var dotNumberChar   = matches[3].Value[0];

                        double pointNumber = Config.ZeroToNineMap[pointNumberChar] * 0.1;
                        double dotNumber   = Config.ZeroToNineMap[dotNumberChar] * 0.01;

                        intNumber = Config.ZeroToNineMap[intNumberChar];

                        result.Value = (intNumber + pointNumber + dotNumber) * 10;
                    }
                    else
                    {
                        var intNumberChar = matches[0].Value[0];

                        if (intNumberChar == '対' || intNumberChar == '对')
                        {
                            intNumber = 5;
                        }
                        else if (intNumberChar == '十' || intNumberChar == '拾')
                        {
                            intNumber = 10;
                        }
                        else
                        {
                            intNumber = Config.ZeroToNineMap[intNumberChar];
                        }

                        result.Value = intNumber * 10;
                    }
                }
            }
            else if (extResult.Data.ToString().Contains("Num"))
            {
                var doubleText = Config.PercentageRegex.Match(resultText).Value;

                if (doubleText.Contains("k") || doubleText.Contains("K") || doubleText.Contains("k") ||
                    doubleText.Contains("K"))
                {
                    power = 1000;
                }

                if (doubleText.Contains("M") || doubleText.Contains("M"))
                {
                    power = 1000000;
                }

                if (doubleText.Contains("G") || doubleText.Contains("G"))
                {
                    power = 1000000000;
                }

                if (doubleText.Contains("T") || doubleText.Contains("T"))
                {
                    power = 1000000000000;
                }

                result.Value = GetDigitValue(resultText, power);
            }
            else
            {
                var doubleText = Config.PercentageRegex.Match(resultText).Value;
                doubleText = ReplaceUnit(doubleText);

                var splitResult = Config.PointRegex.Split(doubleText);
                if (splitResult[0] == "")
                {
                    splitResult[0] = "零";
                }

                var doubleValue = GetIntValue(splitResult[0]);
                if (splitResult.Length == 2)
                {
                    if (Config.NegativeNumberSignRegex.IsMatch(splitResult[0]))
                    {
                        doubleValue -= GetPointValue(splitResult[1]);
                    }
                    else
                    {
                        doubleValue += GetPointValue(splitResult[1]);
                    }
                }

                result.Value = doubleValue;
            }

            result.ResolutionStr = result.Value + @"%";
            return(result);
        }