ShowDoc 内置 Doctrine Inflector 实战指南:PHP 单词复数化、单复数转换与命名风格变形完全解析
ShowDoc 内置 Doctrine Inflector 实战指南PHP 单词复数化、单复数转换与命名风格变形完全解析【免费下载链接】showdocShowDoc is a tool greatly applicable for an IT team to share documents online一个非常适合IT团队的在线API文档、技术文档工具项目地址: https://gitcode.com/gh_mirrors/sh/showdoc导读Doctrine Inflector 是 Doctrine 生态中一个轻量级的 PHP 字符串变形库核心能力包括单词的复数化pluralize、单数化singularize、camelCase 与下划线命名风格互转、单词首字母大写capitalize、URL 友好化urlize与去重音符号unaccent等。本仓库 ShowDoc 的服务器端server/目录通过 Composer 引入了该库doctrine/inflector2.1.0作为illuminate/support的依赖因此它实际已成为 ShowDoc 后端技术栈的一部分。本文将基于仓库内 官方使用文档 的完整脉络结合 源码实现为你系统讲解 Inflector 的安装、工厂创建、多语言支持、自定义规则以及全部核心方法的用法与底层原理。一、Doctrine Inflector 是什么官方文档在 docs/en/index.rst 的开篇即给出定义Inflector 提供用于文本变形的各种方法核心功能包括复数化pluralization单数化singularizationcamelCase 与under_score下划线风格互转单词首字母大写capitalizing words其包描述见 composer.json也印证了定位a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words一个可对单词进行大小写、单复数形式字符串操作的小型库。它不依赖任何第三方运行库仅要求php: ^7.2 || ^8.0并遵循 MIT 许可证。二、安装方式官方文档给出的安装方式是通过 Composer$ composer require doctrine/inflector在本仓库中该依赖已被锁定为2.1.0版本详见根目录 composer.lock约第 207–279 行其依赖关系是illuminate/supportLaravel 组件声明doctrine/inflector: ^1.4|^2.0也就是说 ShowDoc 通过 Laravel 组件间接引入了 Inflector。如果你需要查看已 vendor 到本仓库的源码可直接浏览 server/vendor/doctrine/inflector/src 目录。三、基本用法通过工厂创建 Inflector官方文档指出使用 Inflector 非常简单通过Doctrine\Inflector\InflectorFactory类即可创建Doctrine\Inflector\Inflector实例use Doctrine\Inflector\InflectorFactory; $inflector InflectorFactory::create()-build();默认创建的是**英语English**Inflector。如需使用其他语言将语言常量传给createForLanguage()方法use Doctrine\Inflector\InflectorFactory; use Doctrine\Inflector\Language; $inflector InflectorFactory::createForLanguage(Language::SPANISH)-build();从源码 InflectorFactory.php 可以看到create()本质就是createForLanguage(Language::ENGLISH)的别名而createForLanguage()内部是一个switch分发到对应语言专属的InflectorFactory如果传入不支持的字符串会抛出InvalidArgumentExceptiondefault: throw new InvalidArgumentException(sprintf( Language %s is not supported., $language ));注意Language::*常量的实际取值见 Language.php并非枚举对象而是普通字符串常量例如Language::ENGLISH english、Language::NORWEGIAN_BOKMAL norwegian-bokmal因此createForLanguage()的参数类型是string。四、支持的语言官方文档列出的受支持语言如下常量均定义在Doctrine\Inflector\Language语言常量对应语言源码目录src/Rules/下Language::ENGLISH英语English/Language::ESPERANTO世界语Esperanto/Language::FRENCH法语French/Language::NORWEGIAN_BOKMAL挪威语博克马尔文NorwegianBokmal/Language::PORTUGUESE葡萄牙语Portuguese/Language::SPANISH西班牙语Spanish/Language::TURKISH土耳其语Turkish/需要说明的是实际仓库源码中还存在一个额外的Italian意大利语规则目录Rules/Italian不过它尚未被注册进InflectorFactory的switch分发中——从源码结构看这可能是为后续版本预留的语言支持官方文档未将其列入。每种语言的规则目录都统一包含四个文件Inflectible.php正则变换与不规则词表、Uninflected.php不可变形词表、Rules.php组装规则集、InflectorFactory.php语言专属工厂。五、手动构造 Inflector如果不希望使用工厂也可以手动组装 Inflector。官方文档给出的构造示例use Doctrine\Inflector\CachedWordInflector; use Doctrine\Inflector\RulesetInflector; use Doctrine\Inflector\Rules\English; $inflector new Inflector( new CachedWordInflector(new RulesetInflector( English\Rules::getSingularRuleset() )), new CachedWordInflector(new RulesetInflector( English\Rules::getPluralRuleset() )) );这里涉及 Inflector 的核心设计——装饰器链对应三个类Inflector.php构造函数接收两个WordInflector分别用于单数化singularizer与复数化pluralizer。pluralize()与singularize()方法内部只是简单地把任务委托给这两个组件见源码第 491–506 行。RulesetInflector.php真正的规则引擎。它对一组Ruleset依次执行三条匹配规则若单词命中uninflected不可变形模式原样返回若命中不规则词表irregular/substitutions且结果与输入不同返回该结果若命中正则变换regular/transformations且结果与输入不同返回该结果全部未命中则保持原样。CachedWordInflector.php带内存缓存的装饰器用$this-cache[$word] ?? $this-cache[$word] ...记住每个词的变形结果避免对高频词反复执行正则匹配。工厂的build()方法见 GenericLanguageInflectorFactory.php正是把「语言默认规则集 用户自定义规则集」统一组装成上述装饰器链。规则集内部结构每个语言的Rules.php会构建一个Ruleset它由三部分组成见 Ruleset.phpRegular正则变换Transformations集合按顺序执行正则替换第一个命中的变换生效见 Transformations.php。每个Transformation由Pattern与替换字符串构成最终通过preg_replace完成替换见 Transformation.php。Uninflected不可变形Patterns集合会被合并为一个/^(?:...)$/i的整体正则做整词匹配见 Patterns.php命中即不做变形。Irregular不规则词Substitutions集合基于大小写不敏感的映射表做精确整词替换并自动保留首字母大小写见 Substitutions.php。Pattern的构造有个细节如果模式字符串以/开头则直接作为完整正则使用否则会自动包装为/模式/i大小写不敏感见 Pattern.php。英语规则示例英语规则定义在 Rules/English/Inflectible.php 与 Rules/English/Uninflected.php。以单数化规则为例典型条目包括yield new Transformation(new Pattern((x|ch|ss|sh)es$), \1); // boxes - box yield new Transformation(new Pattern(([^aeiouy]|qu)ies$), \1y); // babies - baby yield new Transformation(new Pattern(s$), ); // browsers - browser而 Rules/English/Rules.php 负责组装单数规则集使用「翻转后的不规则词表」getFlippedSubstitutions()即把复数形式映射回单数形式复数规则集则直接使用原始不规则词表。六、添加新语言支持官方文档说明若想为 Inflector 增加新语言支持可以参考Doctrine\Inflector\Rules命名空间下已有语言的实现以及Doctrine\Tests\Inflector\Rules下的测试用例复制其中一个语言目录并按目标语言更新规则即可。从仓库源码看一种新语言需要提供四部分Inflectible.php——用yield生成器给出复数化与单数化的Transformation列表以及不规则词Substitution列表Uninflected.php——给出不可变形词Pattern列表Rules.php——实现getSingularRuleset()与getPluralRuleset()InflectorFactory.php——继承GenericLanguageInflectorFactory实现抽象方法返回上述两个规则集同时在InflectorFactory::createForLanguage()的switch中注册对应分支。完成开发后按官方文档指引向doctrine/inflector仓库提交 Pull Request 即可。七、自定义规则工厂级定制官方文档提供了一套完整的自定义规则示例演示如何通过withSingularRules()与withPluralRules()为工厂追加自定义的单复数规则use Doctrine\Inflector\InflectorFactory; use Doctrine\Inflector\Rules\Pattern; use Doctrine\Inflector\Rules\Patterns; use Doctrine\Inflector\Rules\Ruleset; use Doctrine\Inflector\Rules\Substitution; use Doctrine\Inflector\Rules\Substitutions; use Doctrine\Inflector\Rules\Transformation; use Doctrine\Inflector\Rules\Transformations; use Doctrine\Inflector\Rules\Word; $inflector InflectorFactory::create() -withSingularRules( new Ruleset( new Transformations( new Transformation(new Pattern(/^(bil)er$/i), \1), new Transformation(new Pattern(/^(inflec|contribu)tors$/i), \1ta) ), new Patterns(new Pattern(singulars)), new Substitutions(new Substitution(new Word(spins), new Word(spinor))) ) ) -withPluralRules( new Ruleset( new Transformations( new Transformation(new Pattern(^(bil)er$), \1), new Transformation(new Pattern(^(inflec|contribu)tors$), \1ta) ), new Patterns(new Pattern(noflect), new Pattern(abtuse)), new Substitutions( new Substitution(new Word(amaze), new Word(amazable)), new Substitution(new Word(phone), new Word(phonezes)) ) ) ) -build();这段代码展示了自定义规则集的完整组成语法其中每个Ruleset由三个参数构成参数类作用第一个Transformations一组按顺序匹配的正则变换Transformation第二个Patterns一组命中后不做变形的整词模式Pattern第三个Substitutions一组不规则整词替换Substitution从Word到Wordreset 参数替换还是追加withSingularRules()/withPluralRules()还接受第二个布尔参数reset默认false。从 GenericLanguageInflectorFactory.php 的实现看reset false默认自定义规则集通过array_unshift插入到规则列表最前即优先于语言默认规则执行reset true先清空已有规则列表再用自定义规则集替换即完全抛弃该语言的默认规则。工厂的build()最终会把singularRulesets/pluralRulesets展开为多个RulesetInflector参数外层再套上CachedWordInflector完成缓存。八、空操作No-opInflectorNull Object 模式官方文档介绍Doctrine\Inflector\NoopWordInflector可用于配置一个对复数化/单数化不做任何操作的 Inflector输入是什么输出就是什么这是 Null Object 设计模式 的一个实现。use Doctrine\Inflector\Inflector; use Doctrine\Inflector\NoopWordInflector; $inflector new Inflector(new NoopWordInflector(), new NoopWordInflector());对应的实现非常简洁NoopWordInflector.phpclass NoopWordInflector implements WordInflector { public function inflect(string $word): string { return $word; } }其价值在于当业务层需要「可插拔」的变形策略例如某些场景关闭单复数转换时可以无侵入地替换掉真实规则而无需改动调用方代码。九、核心 API 逐一详解以下方法均定义在 Inflector.php 中除pluralize/singularize依赖上述装饰器链外其余多为纯字符串/正则处理。1. tableize类名 → 数据表名将ModelName转换为model_nameecho $inflector-tableize(ModelName); // model_name实现第 232–244 行先用正则~(?\w)([A-Z])~u在每个大写字母前插入下划线再通过mb_strtolower()转小写使用多字节安全函数兼容 UTF-8 字符。2. classify表名/下划线 → 类名将model_name转换为ModelNameecho $inflector-classify(model_name); // ModelName实现第 249–252 行调用ucwords($word, _-)以空格、下划线、连字符为分隔符逐词大写再移除这三种分隔符。因此my-page_name也会变成MyPageName。3. camelize表名 → 驼峰命名camelize 复用 classify 后将首字符转为小写echo $inflector-camelize(model_name); // modelName实现第 257–260 行就是lcfirst($this-classify($word))很适合生成 PHP 方法名或 JavaScript 变量名。4. capitalize可配置分隔符的首字母大写官方文档明确指出该方法行为类似 PHP 内置的ucwords但允许自定义单词分隔符而非只按空白分割$string top-o-the-morning to all_of_you!; echo $inflector-capitalize($string); // Top-O-The-Morning To All_of_you! echo $inflector-capitalize($string, -_ ); // Top-O-The-Morning To All_Of_You!实现第 287–290 行本质就是ucwords($string, $delimiters)第二个参数$delimiters的默认值是 \n\t\r\0\x0B-空白类字符加连字符。注意第一个调用未传入_作为分隔符因此all_of_you中只有all被大写第二个调用显式传入-_ 三个词都被正确大写。5. pluralize / singularize复数化与单数化返回单词的复数 / 单数形式echo $inflector-pluralize(browser); // browsers echo $inflector-singularize(browsers); // browser实现第 491–506 行分别委托给构造时注入的singularizer/pluralizer即上一节描述的三层装饰器链CachedWordInflector → RulesetInflector → 语言规则集。英语规则中如(x|ch|ss|sh)es$ → \1覆盖boxes/boxes类词形s$ → 覆盖常规复数词尾。6. urlize生成 URL 友好字符串从一段文本生成 URL 友好的 slugecho $inflector-urlize(My first blog post); // my-first-blog-post实现第 448–482 行分四步先unaccent()去除重音与非法字符再统一转小写优先mb_strtolower随后依次执行四组正则替换非单词字符 → 空格、连续大写拆分为下划线、字母数字边界的大写拆分、非法字符序列 → 连字符最后用trim($urlized, -)去掉首尾多余的连字符。因此它不仅能处理普通文本也能处理camelCase混合文本的 slug 化。7. unaccent去重音符号去除字符串中的重音字符echo $inflector-unaccent(año); // ano实现第 335–438 行较为精巧若字符串不含高位字节/[\x80-\xff]/不命中则直接返回通过seemsUtf8()第 297–326 行逐字节按 UTF-8 编码特征判断区分 UTF-8 与 ISO-8859-1UTF-8 场景使用strtr()对照ACCENTED_CHARACTERS常量映射表第 26–215 行覆盖数百个拉丁扩展字符如Ä → Ae、ß → ss、Œ → OE逐一替换非 UTF-8 场景则按 ISO-8859-1 的字节码表处理单字节与双字节映射。十、Legacy API1.x 兼容说明官方文档特别提醒Inflector 1.x 时代的 API 仍然可用但将在未来版本中弃用并计划在3.0 版本中移除同时除英语外的多语言支持仅存在于 2.0 新 API 中。因此对于新代码官方建议统一使用本文介绍的 2.x 工厂 APIInflectorFactory::create()/createForLanguage()避免后续升级时遭遇破坏性变更。十一、在本仓库中的实际位置与版本最后把视角拉回本仓库方便读者直接查阅官方文档 server/vendor/doctrine/inflector/docs/en/index.rst本文的骨架来源全部源码 server/vendor/doctrine/inflector/src包信息与 PHP 版本要求 server/vendor/doctrine/inflector/composer.json锁定版本2.1.0与依赖方 根目录 composer.lockdoctrine/inflector作为illuminate/support的依赖被引入版本约束^1.4|^2.0十二、致谢与规则来源按官方文档说明本库的语言规则改编自多个知名开源实现包括 Ruby On Rails 的 ActiveSupport Inflector、ICanBoogie Inflector 以及 CakePHP Inflector。其中英语的复数/单数正则体系、不规则词表等规则设计很大程度上延续了这些前辈项目的成熟方案这也是 Inflector 能在多语言、多框架环境中保持规则一致性的原因。【免费下载链接】showdocShowDoc is a tool greatly applicable for an IT team to share documents online一个非常适合IT团队的在线API文档、技术文档工具项目地址: https://gitcode.com/gh_mirrors/sh/showdoc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

5分钟搞懂gchenwenguang.com.cn避坑指南

5分钟搞懂gchenwenguang.com.cn避坑指南

5分钟搞懂gchenwenguang.com.cn避坑指南 复制来的代码跑不通,报错信息一堆却找不到头绪?别急,这正是很多工程师在接触 gchenwenguang.com.cn…

2026/9/23 1:17:14 阅读更多 →
C++课程设计:基于Qt的信号槽与类继承实现植物大战僵尸

C++课程设计:基于Qt的信号槽与类继承实现植物大战僵尸

简介:面向C课程设计与Qt初学者的完整期末项目方案,以植物大战僵尸为选题,演示了Graphics View框架下的游戏开发全流程。资源包含完整可编译源码与开发文档,源码采用面向对象设计,通过封装、继承与多态实现植物基类&…

2026/9/23 1:17:14 阅读更多 →
DC-1靶机实战:Drupal漏洞与SUID提权完整夺旗指南

DC-1靶机实战:Drupal漏洞与SUID提权完整夺旗指南

简介:面向网络安全初学者的夺旗(CTF)靶机实操教程,以Vulnhub DC-1靶机为实验环境,完整演示从环境搭建、局域网主机发现、端口扫描到漏洞利用与权限提升的攻防链路。压缩包内为PDF文档,仅1个文件&#xff0c…

2026/9/23 1:16:14 阅读更多 →

最新新闻

ECG心电信号分类实战:Python与Matlab双版本实现与避坑指南

ECG心电信号分类实战:Python与Matlab双版本实现与避坑指南

简介:这是一份面向医学数据分析、生物医学工程及机器学习初学者的ECG心电信号分类资源包,整合Python与MATLAB两套实现方案,帮助学习者掌握从信号预处理、特征提取到分类建模的完整流程。压缩包共825个文件,约6.25MB,核…

2026/9/24 0:46:51 阅读更多 →
YOLOv7打电话检测实战:双格式数据集与训练部署全解析

YOLOv7打电话检测实战:双格式数据集与训练部署全解析

简介:YOLOv7打电话行为检测项目,面向计算机视觉开发者与边缘设备部署场景,适合需要快速落地手持电话识别功能的工程人员及高校研究者。压缩包提供训练好的权重、完整训练代码以及配套数据集,可直接加载权重进行图片/视频推理&…

2026/9/24 0:46:51 阅读更多 →
ResNet50迁移学习做垃圾分类:数据对齐、模型改造与可解释性实战

ResNet50迁移学习做垃圾分类:数据对齐、模型改造与可解释性实战

简介:本资源是一份基于ResNet50迁移学习实现垃圾分类任务的完整Python项目,面向计算机、人工智能、数据科学等专业学生及初入CV领域的开发者,适用于课程设计、毕业设计、大作业或技术验证场景。项目已通过实测运行,包含模型训练、…

2026/9/24 0:46:51 阅读更多 →
基于SpringBoot的仓储管理系统-附源码

基于SpringBoot的仓储管理系统-附源码

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/9/24 0:44:50 阅读更多 →
ISO 24748-3指南:软件生命周期过程落地与裁剪实战

ISO 24748-3指南:软件生命周期过程落地与裁剪实战

简介:ISO/IEC/IEEE 24748-3:2020 是一份系统与软件工程领域生命周期管理国际标准,旨在为组织实施 ISO/IEC/IEEE 12207(软件生命周期过程)提供详细指南。该标准共75页,完整英文电子版,适用于软件工程师、系统…

2026/9/24 0:44:50 阅读更多 →
Linux与Windows交替输出实现原理对比

Linux与Windows交替输出实现原理对比

1. 这道题到底在考什么:从“交替输出”看操作系统思维的本质差异刚看到这个标题——“Linux课后作业,用Windows下批处理和Linux下的shell脚本完成,两文本交替输出”——我第一反应不是写代码,而是笑了。不是笑题目难,是…

2026/9/24 0:44:50 阅读更多 →

日新闻

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:19 阅读更多 →
单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:19 阅读更多 →
C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/24 0:00:19 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →