Skip to main content
Version: 4.0 (next)

Parse localized number words

Use TryToNumber at an input boundary where invalid integer words are expected. Use ToNumber when invalid text is exceptional and should throw. The corresponding decimal APIs are TryToDecimalNumber and ToDecimalNumber. All four require an explicit CultureInfo, because the same words, magnitude system, and token rules do not mean the same thing in every culture.

Example

This executable parses positive and negative integers, handles an unrecognized word, parses English and French decimal words, and preserves an authored decimal scale:

Program.cs
using System.Globalization;
using Humanizer;

var culture = CultureInfo.GetCultureInfo("en-US");

var parsed = "two hundred five".ToNumber(culture);
var succeeded = "negative forty-two".TryToNumber(
out var negative,
culture,
out var unrecognized);
var rejected = "two otters".TryToNumber(
out var invalid,
culture,
out var invalidWord);
var decimalSucceeded = "one point five zero".TryToDecimalNumber(
out var decimalValue,
culture,
out var decimalUnrecognized);
var decimalRejected = "one point ten".TryToDecimalNumber(
out var invalidDecimal,
culture,
out var invalidDecimalWord);
var frenchCulture = CultureInfo.GetCultureInfo("fr-FR");
var frenchSucceeded = "un virgule deux".TryToDecimalNumber(
out var frenchDecimal,
frenchCulture,
out var frenchUnrecognized);

Console.WriteLine($"Integer: {parsed}");
Console.WriteLine($"Negative: {(succeeded ? negative : unrecognized)}");
Console.WriteLine($"Rejected: {(rejected ? invalid : invalidWord)}");
Console.WriteLine(
$"Decimal: {(decimalSucceeded ? decimalValue.ToString(CultureInfo.InvariantCulture) : decimalUnrecognized)}");
Console.WriteLine(
$"Invalid decimal: {(decimalRejected ? invalidDecimal : invalidDecimalWord)}");
Console.WriteLine(
$"French decimal: {(frenchSucceeded ? frenchDecimal.ToString(frenchCulture) : frenchUnrecognized)}");
Output
Integer: 205
Negative: -42
Rejected: otters
Decimal: 1.50
Invalid decimal: ten
French decimal: 1,2

Handle expected failure

The longest TryToNumber overload returns:

  • false when a token cannot be recognized.
  • 0 in the numeric result.
  • The first unrecognized word in the final out parameter.

That token is useful for field validation messages. Do not catch FormatException for routine input when TryToNumber expresses the branch directly.

Parse localized decimal words

ToDecimalNumber accepts a localized integer phrase followed by exactly one locale-specific decimal marker and between 1 and 28 localized fractional digit words. English accepts one point two, French accepts un virgule deux, Hindi accepts एक दशमलव दो, and Urdu accepts ایک اعشاریہ دو. The integer part may be omitted, and a locale-supported negative affix applies to the complete value. The authored decimal scale is preserved, including trailing zeros and signed zero. Whitespace-tokenized grammars require boundaries around the decimal marker and each fractional digit, while negative affixes keep their profile-authored boundary. Joined-script profiles such as Chinese use their authored joined tokenization instead.

The integer side and each fractional digit reuse the selected culture's generated number-word profiles. For example, en-IN accepts ninety-three shankh point one, while en-US does not. Locale variants and same-language descendants inherit their localized parent profile; unsupported languages never fall back to English. English preserves scale composition past the long range when the final value fits in decimal; other cultures use the range accepted by their own words-to-number grammar.

Locale-authored decimal markers use reviewed spoken terms where available. Locales without a spoken marker use their standard decimal separator token.

For malformed input, unsupported cultures, or values that cannot fit in decimal, TryToDecimalNumber returns false, sets the result to 0m, and reports a best-effort unrecognized token or phrase when that overload is used. For null or empty input, that reported value is an empty string. ToDecimalNumber instead throws:

ConditionException
null inputArgumentNullException
Malformed or out-of-range phraseFormatException
Unsupported cultureNotSupportedException

Convert to a narrower type

ToNumber returns long. If the application requires int, use a checked conversion after successful parsing:

var value = checked((int)parsedLong);

Treat number words as a defined input format

The parsers support only the locales and word forms represented by Humanizer's generated profiles. They are not general natural-language parsers. Preserve the explicit culture from the user-input boundary.