/// <summary> /// The method to convert number words from text to number /// </summary> /// <param name="text">The text to be converted.</param> /// <returns>Zero if the text is not valid; otherwise the converted value;</returns> public static long DoConvert(string text) { long result = 0; long section = 0; ParseState parseState = ParseState.FirstWord; string[] split = text.ToLower().Split(' '); errorText.Clear(); if (IsValid(text)) { for (int index = 0; index < split.Length; index++) { string item = split[index]; string nextItem = index < split.Length - 1 ? split[index + 1] : string.Empty; ParseState nextState = GetWordType(nextItem); switch (parseState) { case ParseState.FirstWord: section = GetValueForFirstDigit(item); parseState = nextState; break; case ParseState.SecondDigit: section += GetValueForDigit(item); break; case ParseState.Multiplier: section *= multiples[item]; break; case ParseState.HundredSeparators: section *= 100; switch (nextState) { case ParseState.Multiplier: section *= multiples[nextItem]; index++; parseState = ParseState.Multiplier; break; case ParseState.And: index += 2; nextItem = split[index]; nextState = GetWordType(nextItem); switch (nextState) { case ParseState.FirstWord: section += GetValueForFirstDigit(nextItem); if (index < split.Length - 1) { nextItem = split[++index]; nextState = GetWordType(nextItem); if (nextState.Equals(ParseState.SecondDigit)) { section += GetValueForDigit(nextItem); if (index + 1 < split.Length) { nextItem = split[index + 1]; parseState = GetWordType(nextItem); } else { nextState = ParseState.None; } } } break; case ParseState.SecondDigit: section += GetValueForDigit(nextItem); break; default: break; } break; } break; } if (nextState.Equals(ParseState.None) || nextState.Equals(ParseState.And)) { result += section; section = 0; } } } return(errorText.Length > 0 ? 0 : result); }
/// <summary> /// The method to determine if the text contains valid text elements. /// </summary> /// <param name="text">The text to be processed. Word items such as ten, seventeen, or eighty four.</param> /// <returns>True if the space separated number words are valid: False if no text, blank items.</returns> public static bool IsValid(string text) { bool seenAnd = false; ParseState parseState = ParseState.FirstWord; errorText.Clear(); string[] split = text.ToLower().Split(' '); if (split.Length == 0) { errorText.AppendLine("Blank text is not valid"); } bool lastWasDigit = false; bool lastWasAnd = false; int digitCount = 0; foreach (string item in split) { if (string.IsNullOrEmpty(item)) { errorText.AppendLine(string.Format("Blank items are not valid")); } else { lastWasAnd = false; if (item.Equals(And)) { if (seenAnd) { errorText.AppendLine("Can not repeat and"); } seenAnd = true; } else { seenAnd = false; if (!(digits.ContainsKey(item) || teens.ContainsKey(item) || tens.ContainsKey(item) || multiples.ContainsKey(item) || seperators.Contains(item))) { errorText.AppendLine(string.Format("The item: {0} is not valid", item)); } } ParseState wordsType = GetWordType(item); switch (parseState) { case ParseState.FirstWord: if (wordsType == ParseState.FirstWord || wordsType == ParseState.SecondDigit) { parseState = ParseState.SecondDigit; lastWasAnd = false; if (wordsType.Equals(ParseState.SecondDigit)) { lastWasDigit = true; digitCount++; } else { lastWasDigit = false; digitCount += 2; } } else { errorText.AppendLine(string.Format("Expecting a number word rather than : {0}", item)); } break; case ParseState.SecondDigit: if (wordsType == ParseState.SecondDigit) { digitCount++; lastWasAnd = false; parseState = ParseState.Multiplier; if (lastWasDigit) { errorText.AppendLine(string.Format("Second digit is not valid {0}", item)); } } else if (wordsType == ParseState.Multiplier) { parseState = ParseState.And; } else if (wordsType == ParseState.HundredSeparators) { parseState = ParseState.And; if (!lastWasDigit) { errorText.AppendLine("The Hundred can only follow a digit word"); } } else { string type = wordsType.Equals(ParseState.FirstWord) ? "teens or tens" : wordsType.ToString(); errorText.AppendLine(string.Format("Did not expect the word type of {0} in the position of second digit for {1}", type, item)); } break; case ParseState.And: if (wordsType == ParseState.And) { digitCount = 0; parseState = ParseState.FirstWord; lastWasAnd = true; } else { if (wordsType != ParseState.Multiplier) { errorText.AppendLine(string.Format("A multiplier must be followed by the word 'And' rather than {0}", item)); } } break; case ParseState.Multiplier: if (wordsType.Equals(ParseState.HundredSeparators)) { if (digitCount > 2 || !lastWasDigit) { errorText.AppendLine("The Hundred can only follow a digit word"); } } if (wordsType.Equals(ParseState.Multiplier)) { parseState = ParseState.And; } else if (wordsType.Equals(ParseState.SecondDigit)) { parseState = ParseState.SecondDigit; } break; default: errorText.AppendLine(string.Format("Did not expect the word type of {0}", item)); break; } } } if (lastWasAnd) { errorText.AppendLine("The last word can not be 'and' most be followed by a number word"); } return(errorText.Length == 0); }