ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Humanizer WordsToNumberExtension 详解:将拼写数字字符串解析为数值的完整指南

2026/9/29 5:32:58 拓冰建站 浏览量
Humanizer WordsToNumberExtension 详解:将拼写数字字符串解析为数值的完整指南 开发工具【免费下载链接】HumanizerHumanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities项目地址https://gitcode.com/gh_mirrors/hu/Humanizer点击查看免费下载Humanizer 不仅能把数字人性化地转成单词1 → one还提供了一整套逆向解析能力通过WordsToNumberExtension你可以把three hundred twenty-one、forty-two这类拼写形式的数字字符串重新转换回数值。本文以website/versioned_docs/version-3.0.1/api/Humanizer.WordsToNumberExtension.md为骨架完整讲解ToNumber与两个TryToNumber重载的用法、参数语义、返回值与异常行为并结合仓库源码剖析其文化感知culture-aware的解析器实现与测试验证帮助你掌握在 .NET 项目中安全解析单词化数字的完整方案。一、WordsToNumberExtension 概览数字转换的另一半WordsToNumberExtension是一个静态扩展类位于Humanizer命名空间类的定位是Transform humanized string to number; e.g. one 1它与NumberToWordsExtension形成天然对称前者把单词解析回数值后者把数值渲染成单词。在 Humanizer 的生态中这组能力用于处理金额录入、表单校验、语音/聊天文本归一化等场景——用户输入forty-two程序需要得到42。该类自身不持有解析逻辑而是把工作委托给按文化culture解析的转换器。从当前仓库源码看WordsToNumberExtension的三个扩展方法都通过Configurator.GetWordsToNumberConverter(culture)获取转换器后完成解析。类继承关系为System.Object → WordsToNumberExtension静态类。该类共公开 3 个方法先一览方法行为适用场景ToNumber(this string, CultureInfo)严格解析遇到无法识别的单词抛异常输入已确认合法、需要快速取值TryToNumber(this string, out int, CultureInfo)非抛出式解析失败返回false输入可能来自不可控来源用户输入、外部文本TryToNumber(this string, out int, CultureInfo, out string?)非抛出式解析并报告第一个无法识别的单词调试、向用户展示精确错误原因版本说明3.0.1 版本文档中的签名返回int当前仓库源码已将返回值拓宽为long详见本文第七章版本演进下文先按文档 API 讲解再给出源码现状。二、ToNumber严格解析失败即抛异常文档给出的完整签名public static int ToNumber(this string words, System.Globalization.CultureInfo culture);参数wordsstring拼写形式的数字例如three hundred twenty-one、forty-two。不能为null。cultureCultureInfo解析时使用的文化。不同文化对数字有不同的单词表示例如英语的twenty与法语的vingt代表同一个数。返回值与异常返回int单词所代表的整数值。抛出FormatException当输入包含无法识别的单词、或整体无法被解析为数字时文档标注。抛出ArgumentNullException当words为null时文档标注。源码现状补充从当前仓库的默认实现看TokenMapWordsToNumberConverter.Convert在解析失败时抛出的是ArgumentException消息形如Unrecognized number word: {unrecognizedWord}而对null、空串、纯空白输入同样抛出ArgumentException。这与 3.0.1 文档标注的FormatException略有出入使用时应以你所引用的 Humanizer 版本实际行为为准。示例文档原例// English (en-US) three hundred twenty-one.ToNumber(new CultureInfo(en-US)) 321 forty-two.ToNumber(new CultureInfo(en-US)) 42 one thousand.ToNumber(new CultureInfo(en-US)) 1000 // Invalid input throws exception xyz.ToNumber(new CultureInfo(en-US)) throws FormatExceptionRemarks文档明确说明ToNumber是严格解析只要有一个单词无法识别就会抛异常。如果需要不抛异常的非严格版本请使用TryToNumber。三、TryToNumber(out int)不抛异常的安全解析当你无法保证输入一定合法时文档推荐使用TryToNumberpublic static bool TryToNumber(this string words, out int parsedNumber, System.Globalization.CultureInfo culture);参数wordsstring拼写形式的数字例如forty-two、one hundred。不能为null。parsedNumberout int方法返回时若转换成功则包含单词对应的整数值转换失败时该值为0。cultureCultureInfo解析时使用的文化。返回值返回bool转换成功返回true否则返回false。示例文档原例// Successful conversion forty-two.TryToNumber(out int result, new CultureInfo(en-US)) returns true, result 42 // Failed conversion xyz.TryToNumber(out int result, new CultureInfo(en-US)) returns false, result 0Remarks文档指出当你不确定输入是否合法时这是推荐的解析方法——它对无效输入不会抛异常。源码细节这一行为对应IWordsToNumberConverter.TryConvert的约定。需要留意的是接口约定仍规定对null、空串或纯空白输入实现可以抛ArgumentException不支持某 locale 的回退实现则可能抛NotSupportedException。也就是说不抛异常承诺的范围是无法识别的单词/无法解析的短语而不是空输入——实际使用TryToNumber解析前建议先做好空值检查。四、TryToNumber(out int, out string?)定位第一个无法识别的单词这是带诊断信息的重载用于调试或向用户展示精确的错误原因public static bool TryToNumber(this string words, out int parsedNumber, System.Globalization.CultureInfo culture, out string? unrecognizedWord);参数wordsstring拼写形式的数字例如one thousand one。不能为null。parsedNumberout int转换成功时包含整数值失败时为0。cultureCultureInfo解析时使用的文化。unrecognizedWordout string?方法返回false时包含输入中第一个无法识别的单词返回true时该参数为null。返回值返回bool转换成功返回true否则返回false。示例文档原例// Successful conversion one thousand.TryToNumber(out int result, new CultureInfo(en-US), out string? badWord) returns true, result 1000, badWord null // Failed conversion with unrecognized word one xyz three.TryToNumber(out int result, new CultureInfo(en-US), out string? badWord) returns false, result 0, badWord xyzRemarks文档指出该重载对哪个具体单词导致解析失败给出了直接线索非常适合调试或用于向终端用户输出类似无法识别单词xyz的友好错误信息。从源码看这一诊断能力由IWordsToNumberConverter.TryConvert(string, out long, out string?)提供解析器会尽力回传第一个无法解释的 token 或片段。五、底层原理文化感知的解析管线三个扩展方法的实现都极简——真正的复杂度在转换器内部。以WordsToNumberExtension.cs为例public static long ToNumber(this string words, CultureInfo culture) Configurator.GetWordsToNumberConverter(culture).Convert(words); public static bool TryToNumber(this string words, out long parsedNumber, CultureInfo culture) Configurator.GetWordsToNumberConverter(culture).TryConvert(words, out parsedNumber); public static bool TryToNumber(this string words, out long parsedNumber, CultureInfo culture, out string? unrecognizedWord) Configurator.GetWordsToNumberConverter(culture).TryConvert(words, out parsedNumber, out unrecognizedWord);调用链Configurator.GetWordsToNumberConverter(culture)内部调用WordsToNumberConverters.ResolveForCulture(culture)按文化解析出对应的IWordsToNumberConverter实现。转换器注册表WordsToNumberConverterRegistry以英语TokenMapWordsToNumberConverters.En作为默认实现兜底再向注册表注册各语言/文化的具体实现。最终解析交给语言对应的解析器词表token map数据由src/Humanizer/Locales/*.yml中的number.words、number.parse等 locale 编写数据驱动生成源码 XML 注释中明确提到这一点。接口契约IWordsToNumberConverter定义三个成员bool TryConvert(string words, out long parsedValue)非抛出解析parsedValue仅在返回true时有意义bool TryConvert(string words, out long parsedValue, out string? unrecognizedNumber)非抛出解析并报告无法识别的 tokenlong Convert(string words)严格解析失败抛ArgumentException。实现约定对null/空串/空白输入可抛ArgumentException对不支持该 locale 解析的回退实现可抛NotSupportedException。默认解析器的解析流程英语等大量语言默认使用TokenMapWordsToNumberConverter其解析是分阶段进行的空值/纯数字直通若 locale 允许且输入本身就是long可解析的整数文本直接返回规范化对输入Trim按 locale 的规范化配置做归一化符号剥离识别minus、negative等前缀/后缀记录负号序数尝试先尝试序数语法包括精确序数查找、序数缩写如21st、以及词干序数规模后缀的粘连形式基数归约序数不匹配时从左到右带 lookahead前瞻地归约基数短语——精确短语优先然后依次尝试复合规模词对composite scale pairs、粘连规模glued scale、token 直接取值、前瞻复合如twohundred、twoteen、大规模词如thousand、million与乘数 token最后才是加法回退溢出防护全程使用checked运算与上限校验long.MaxValue溢出时返回解析失败而不是抛出异常。此外代码中还有一套紧凑粘连规模计数compact glued scale count的动态规划匹配逻辑TryParseCompactGluedScaleCount用于处理德语等语言中把多个 token 直接拼成一个长单词的形态并带有长度、token 数、每位置状态数的上限保护。多语言解析器家族仓库的Localisation/WordsToNumber目录下按语言语法形态准备了多种解析器例如GenderlessWordsToNumberConverter无语法性别差异的通用基类EastAsianPositionalWordsToNumberConverter东亚位值制InvertedTensWordsToNumberConverter十位倒装如德语LinkedVigesimalWordsToNumberConverter二十进制连锁ContractedScaleWordsToNumberConverter、StemmedScaleWordsToNumberConverter、SuffixScaleWordsToNumberConverter等不同规模词构造方式LocalizedWordsToDecimalNumberConverter与UnsupportedWordsToDecimalNumberConverter小数/不支持 locale 的回退正是这套接口 注册表 按语法形态分类的实现 yml locale 数据的架构让WordsToNumberExtension能以统一 API 覆盖几十种语言。六、实战验证测试用例覆盖的输入形态仓库测试对解析器行为给出了非常具体的证据可作为你使用时的输入形态参考。WordsToNumberTests.csen-US文化覆盖了基础数词zero → 0、one → 1、eleven → 11、ninety five → 95省略前缀的写法hundred five → 105负数minus five → -5、minus one hundred and five → -105、negative three billion → -3000000000序数seventeenth → 17、thirtieth → 30、twenty-seventh → 27、minus twenty-first → -21、one hundred and third → 103、five thousand and ninth → 5009数字序数缩写17th → 17、31st → 31、100th → 100、203rd → 203、minus 21st → -21组合大数one million two hundred thirty four thousand five hundred sixty seven → 1234567、three billion → 3000000000。WordsToNumberLongTests.cs专门验证超出int范围的高位值three billion → 3000000000Lone quadrillion → 1000000000000000Lone quintillion → 1000000000000000000Llong上限附近en-US与en-GB均验证。也就是说当前 Humanizer 不仅能解析int范围内的单词数字还能解析到long范围的高位词billion、trillion、quadrillion、quintillion 等。如果你的业务需要处理超过 21 亿的单词数字应使用当前版本的long返回值 API。七、版本演进从 int 到 long 的返回值变化3.0.1 版本文档中三个方法都标注返回int/out int。而当前仓库源码WordsToNumberExtension.cs中ToNumber返回long两个TryToNumber的out参数均为out long。源码 XML 注释对此的说明是该方法现在返回long以支持 locale 编写数据中超出int.MaxValue的高位数字解析。原有依赖int结果的代码应把接收类型改为long或使用显式的 checked 转换。这意味着两件事若你升级到较新版本把int result words.ToNumber(...)这类代码改成long result ...或var即可平滑迁移仓库的 Analyzers 项目中还提供了WordsToNumberMigrationCodeFixProvider见 src/Humanizer.Analyzers/WordsToNumberMigrationCodeFixProvider.cs从命名与位置可以推断它用于辅助自动化迁移这类 API 调用升级时值得关注。八、相关 API 与延伸阅读小数解析WordsToDecimalNumberExtension与IWordsToDecimalNumberConverter提供单词转小数decimal的对称能力注册入口见 WordsToDecimalNumberConverterRegistry。正向转换NumberToWordsExtension与INumberToWordsConverter提供数字 → 单词的逆向能力与本文的解析器共用同一套 locale 数据。注册与配置Configurator是全部本地化转换器的统一入口LocaliserRegistryT实现了文化 → 实现的注册与继承查找逻辑。API 全貌可继续查阅 Humanizer.WordsToNumberExtension API 文档 以及src/Humanizer/Locales/*.yml中各语言的number.parse数据了解具体语言支持哪些词形。小结WordsToNumberExtension是 Humanizer 中人性化数字能力的逆向通道ToNumber负责严格解析并抛异常两个TryToNumber重载提供安全解析与诊断信息底层由Configurator → IWordsToNumberConverter → 各语言解析器的文化感知管线支撑能处理负数、序数、缩写、粘连长词、复合规模词乃至long范围的高位值。实际编码时记住三条准则不确定输入合法性就用TryToNumber需要向用户解释错误就用带unrecognizedWord的重载需要解析超过 21 亿的数字请使用返回long的当前版本 API。赞分享开发工具【免费下载链接】HumanizerHumanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities项目地址https://gitcode.com/gh_mirrors/hu/Humanizer点击查看免费下载相关推荐Humanizer TupleizeExtensions 详解将整数转换为 single、double、triple 等命名元组字符串Humanizer TupleizeExtensions 详解将整数转换为 single、double、triple 等命名元组字符串 导读 本文深入解析 H开发工具StarRocks str_to_map 字符串函数详解将分隔符文本解析为 Map 的完整指南StarRocks str_to_map 字符串函数详解将分隔符文本解析为 Map 的完整指南 str_to_map 是 StarRocks 提供的高阶字符串数据库OLAP数据仓库大数据湖仓一体数据分析X6 边样式完全指南从默认边、渐变与交错填充到自定义图形与点击事件X6 边样式完全指南从默认边、渐变与交错填充到自定义图形与点击事件 导读 本文以 X6AntV 旗下基于 SVG 与 HTML 渲染的 JavaScript开发工具上一篇JmalCloud常见问题解答从安装到使用的15个实用技巧下一篇微信聊天记录永久保存终极指南用免费开源工具WeChatMsg掌控你的数字记忆创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考