
开发工具【免费下载链接】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 是面向 .NET 的字符串、枚举、日期与数字人性化处理库其复数/单数变换能力由词汇表Vocabulary与曲折变化Inflector机制共同支撑。本文围绕Humanizer.Plurality枚举展开说明它如何作为复数性提示贯穿Pluralize/Singularize的调用语义并结合 Plurality.cs 源码与 InflectorTests.cs 测试用例讲清三态枚举背后的实现原理与实战用法。读完本文你将掌握在何种场景下向 Humanizer 传递已知/未知复数性提示以及如何避免双重复数化与误单数化。一、Plurality 枚举三态复数性提示契约Plurality是定义在Humanizer命名空间下的公开枚举其作用在 XML 注释中描述得非常明确为 Humanizer 提供关于一个单词是单数、复数还是复数性未知的提示Provides hint for Humanizer as to whether a word is singular, plural or with unknown plurality。该枚举定义于 src/Humanizer/Plurality.cs完整成员如下成员数值语义来自 XML 注释Singular0该单词是单数The word is singularPlural1该单词是复数The word is pluralCouldBeEither2无法确定其复数性I am unsure of the plurality对应的 API 参考文档位于 website/versioned_docs/version-3.0.1/api/Humanizer.Plurality.md三个成员与上述定义一一对应。从枚举的数值设计看Singular 0、Plural 1、CouldBeEither 2的连续递增编号暗示了确定性递减的语义层级从明确单数、明确复数到无法判断。这种三态设计在自然语言处理中很常见——很多英文单词如 series、fish 这类不可数/零复数词从形态上无法直接断定其单复数需要显式声明不确定状态。二、Plurality 如何进入 Humanizer 的 API 语义值得说明的是Plurality枚举本身在公开 API 中并未直接作为方法参数出现但它的三态语义被完整映射到了InflectorExtensions的布尔参数上从源码结构看可以这样对应理解已知单数Singular→ 调用Pluralize(word, inputIsKnownToBeSingular: true)已知复数Plural→ 调用Singularize(word, inputIsKnownToBePlural: true)复数性未知CouldBeEither→ 将对应参数传falseHumanizer 会进入检查所有可能性的防御式处理分支。入口扩展方法定义在 src/Humanizer/InflectorExtensions.cs[return: NotNullIfNotNull(nameof(word))] public static string? Pluralize(this string? word, bool inputIsKnownToBeSingular true) Vocabularies.Default.Pluralize(word, inputIsKnownToBeSingular); public static string Singularize(this string word, bool inputIsKnownToBePlural true, bool skipSimpleWords false) Vocabularies.Default.Singularize(word, inputIsKnownToBePlural, skipSimpleWords);两个参数的含义与默认值如下参数默认值含义inputIsKnownToBeSingulartrue调用者确定输入是单数时保持默认若输入可能是复数避免双重复数化传falseinputIsKnownToBePluraltrue调用者确定输入是复数时保持默认若输入可能是单数避免错误单数化传falseskipSimpleWordsfalse为true时跳过对仅以字母 s 结尾的简单单词的单数化避免把 ross 误变成 ros从调用关系看扩展方法将参数原样透传给Vocabularies.Default.Pluralize/Singularize见 src/Humanizer/Inflections/Vocabularies.cs而真正消费复数性提示的是 Vocabulary 内部实现。三、源码级原理未知复数性时的双向检查防御逻辑Plurality的CouldBeEither状态在Vocabulary.Pluralize/Singularize中对应着一套严谨的回退逻辑。以单数化为例Vocabulary.cs 中的实现为if (inputIsKnownToBePlural) { return result ?? word; } // the Plurality is unknown so we should check all possibilities var asPlural ApplyRules(plurals, word, false); if (asPlural word || string.Equals(word s, asPlural, StringComparison.OrdinalIgnoreCase)) { return result ?? word; } var asPluralAsSingular ApplyRules(singulars, asPlural, false); if (asPluralAsSingular ! word || result word) { return result ?? word; } return word;这段代码的执行路径可以拆解为已知复数inputIsKnownToBePlural: true直接应用单数化规则规则无匹配时原样返回单词不做额外猜测未知复数Plurality的CouldBeEither场景先把单词当复数规则跑一遍得到asPlural若asPlural与原词相同或仅是加了个 s 的简单形式说明它本来就像复数直接返回规则单数化结果兜底校验再对asPlural反向做一次单数化得到asPluralAsSingular若反向结果能还原为原词且直接单数化结果与原词不同才返回直接结果否则保守地返回原词。Pluralize侧有对称的逻辑Vocabulary.cs当inputIsKnownToBeSingular: false时会先把输入按单数规则处理再按复数规则反向验证若单数化后又复数化能回到原词、且直接复数化结果与原词不同则返回原词以规避双重复数化。Vocabulary还内置了三条预处理/后处理路径与上述防御逻辑协同纯字母 s 处理LetterS方法正则^([sS])[sS]*$把像 s、SS 这样的输入直接追加 s避免被普通规则误伤复合词头部处理CompoundHeadLength检测以 per 分隔的复合词如 meter per second只对头部做变格保留分母不变不可数词短路IsUncountable命中 fish 这类词时直接原样返回wholeWordMatch true不参与任何规则匹配。四、默认词汇表规则、不规则词与不可数词的注册体系复数性判断最终落到Vocabularies.BuildDefault()构建的默认词汇表上src/Humanizer/Inflections/Vocabularies.cs它由三类注册方法组成对应Vocabulary的公开 API方法用途默认表示例AddPlural(rule, replacement)注册复数化正则规则(x\|ch\|ss\|sh)$→$1esbox → boxes([^aeiouy]\|qu)y$→$1iescity → citiesAddSingular(rule, replacement)注册单数化正则规则s$→(vert\|ind)ices$→$1exvertices → vertexAddIrregular(singular, plural, matchEnding)注册不规则词对person/people、child/children、foot/feet、goose/geeseAddUncountable(word)注册不可数词fish、personnel复数形式与单数相同AddIrregular的matchEnding参数值得注意为true默认时生成(x)xx$结尾匹配规则允许在长词末尾生效为false时使用^singular$/^plural$精确匹配只作用于独立单词。默认表中 olive、ex、is、was、that、this、bus、die、tie 等词均以matchEnding: false注册避免对 olives 以外的词造成误伤。AddAcronym方法则负责维护缩写词的大小写如 HTML确保变格过程中不破坏缩写形态。需要说明的是Vocabulary目前仅支持单一默认词汇表Vocabularies.Default不支持多词汇表并行或删除已注册规则见 Vocabulary.cs 的类注释。五、测试验证三态提示如何被真实场景覆盖InflectorTests.cs 中的测试用例直接验证了已知/未知复数性四象限的幂等性。以InflectionsPreserveAllCaps为例第 35-47 行[InlineData(SINGULAR TYPE NAME, SINGULAR TYPE NAMES)] [InlineData(BUS, BUSES)] [InlineData(PERSON, PEOPLE)] public void InflectionsPreserveAllCaps(string singular, string plural) { Assert.Equal(plural, singular.Pluralize()); Assert.Equal(singular, plural.Singularize()); Assert.Equal(plural, singular.Pluralize(inputIsKnownToBeSingular: false)); Assert.Equal(plural, plural.Pluralize(inputIsKnownToBeSingular: false)); Assert.Equal(singular, singular.Singularize(inputIsKnownToBePlural: false)); Assert.Equal(singular, plural.Singularize(inputIsKnownToBePlural: false)); }该测试同时验证了三种关键行为全大写保留无论输入是 BUS 还是 PERSON变换后保持全大写形态未知复数性下的幂等plural.Pluralize(inputIsKnownToBeSingular: false)仍返回 BUSES/PEOPLE 而不是 BUSESES证明未知场景不会双重复数化未知单数性下的幂等singular.Singularize(inputIsKnownToBePlural: false)仍返回 BUS/PERSON不会错误地去尾 s。InflectsCompoundRates第 49-70 行则覆盖了 meter per second → meters per second、foot per second → feet per second 等复合词场景且同样在四种已知/未知组合下断言幂等。与之相对的DoesNotTreatUnstructuredPhrasesAsCompoundRates第 72-80 行验证了 as per request、meter/per/second 这类非结构化短语不会被误当作 per 复合词处理。此外skipSimpleWords: true在测试第 137 行被用于验证不会把仅以 s 结尾的简单词错误单数化如 ross这与Singularize参数文档中的说明一致InflectorExtensions.cs。六、实战建议何时使用何种复数性提示综合枚举语义与源码实现可以给出如下使用准则数据来自受控词汇枚举名、类型名、业务字典直接使用默认值inputIsKnownToBeSingular: true/inputIsKnownToBePlural: true此时 Humanizer 按已知状态走最短路径性能最优数据来自用户输入或自由文本对应CouldBeEither将提示参数显式传false让 Humanizer 进入双向检查防御逻辑。例如把一段可能已经复数化的文本交给Pluralize前传inputIsKnownToBeSingular: false可避免 cats → catses处理纯以 s 结尾的人名/专名单数化时配合skipSimpleWords: true避免 ross → ros 的误变依赖默认词汇表能力边界Vocabulary面向美式英语US English设计不规则词、不可数词与正则规则均内置于Vocabularies.Default如需覆盖新词可在进程启动时通过AddIrregular、AddUncountable、AddPlural等公开方法向默认表补充规则。Plurality枚举的价值在于它把单词复数性这一模糊概念显式化为三态契约Singular、Plural与CouldBeEither。在 Humanizer 的公开 API 中该契约通过inputIsKnownToBeSingular/inputIsKnownToBePlural两个布尔参数落地在Vocabulary内部它则转化为一套以检查所有可能性为核心的双向规则验证算法。理解这三态语义就能在字符串人性化处理中精准规避双重复数化与误单数化这两类最常见的边界问题。赞分享开发工具【免费下载链接】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 的 Plurality 枚举单数、复数与未知词性提示的语义与底层实现解析Humanizer 的 Plurality 枚举单数、复数与未知词性提示的语义与底层实现解析 Plurality 是 Humanizer 词形变化Infle开发工具Humanizer 中的 Plurality 枚举单复数语义提示与屈折变换的底层支撑Humanizer 中的 Plurality 枚举单复数语义提示与屈折变换的底层支撑 导读 Plurality 是 Humanizer 中一个轻量但关键的枚举开发工具Humanizer 复数提示枚举 Plurality 深度解析单复数判定、歧义处理与词形变换实战Humanizer 复数提示枚举 Plurality 深度解析单复数判定、歧义处理与词形变换实战 导读 Plurality 是 Humanizer 公开 AP开发工具上一篇10个Rickshaw常见问题解决方案快速解决JavaScript图表库使用难题下一篇DDGS错误处理完全指南RatelimitException与TimeoutException解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考