SMOG 公式 JavaScript 实现:文本可读性量化与自动化检测

发布时间:2026/10/18 9:02:08
SMOG 公式 JavaScript 实现:文本可读性量化与自动化检测 简介smog-formula 是一份基于 1969 年 SMOGGobbledygook 的简单度量公式实现文本阅读难易程度检测的 JavaScript 工具包面向需要评估英文文本可读性等级的前端开发者、教育技术研究者与内容编辑。它通过统计句子数与多音节词数量快速换算出对应的阅读年级水平适用于教材分级、文章难度评估等场景。资源包共 12 个文件以 json 配置、js 源码、yml 工作流配置为主另含 md 说明、license 授权文件及 editorconfig、prettierignore 等工程规范文件压缩包整体约 6KB体积轻量、结构规整。该包仅支持 ESM需 Node 12 环境并以 import 方式引入核心导出 smogFormula 方法传入句子数与多音节词数即可得到可读性分值。目前已有 368 人学习下载适合希望快速集成可读性检测能力、了解 SMOG 公式工程化实现的读者参考使用。1. 文本可读性还能算出来SMOG 公式到底在测什么你可能遇到过这种场景辛辛苦苦写完一份产品说明、一段帮助文档甚至一篇技术博客发出去之后收到的反馈却是“看不懂”“太绕了”。问题出在哪是句子太长还是词太生僻靠感觉判断往往不靠谱。SMOG 公式就是干这个的——它用一套固定的计算规则把一段文本的阅读难度换算成一个“年级水平”数值。SMOG 是 Simple Measure of Gobbledygook 的缩写1969 年由 G. Harry McLaughlin 提出专门用来估算读者需要接受多少年教育才能顺畅理解一段文字。它最初用在医疗健康材料领域后来被教育、出版、政府文档等场景广泛采用。这个资源是一个 JavaScript 实现的 SMOG 公式计算模块核心逻辑不复杂但把多音节词统计、句子切分、公式套用这几步串起来了。适合谁用写文档的、做内容审核的、搞教育产品的以及任何想给文本难度加一个量化指标的前端或 Node.js 开发者。2. SMOG 公式的计算原理与 JavaScript 实现拆解2.1 公式本身从多音节词到 SMOG 指数SMOG 公式的核心变量只有一个多音节词的数量。所谓多音节词在英文语境下通常指包含三个或以上音节的词。公式的标准形式是SMOG 1.0430 × √(多音节词数 × (30 / 句子数)) 3.1291这个公式的直觉是一段文本里多音节词越密集读者需要的教育年限就越高。乘以 30/句子数 是为了把结果归一化到“每 30 个句子”的基准上这样不同长度的文本之间可以横向比较。最后加上的 3.1291 是经验修正项让结果更贴近实际年级水平。注意SMOG 公式对句子数有最低要求——如果句子数少于 30计算结果会偏乐观通常建议文本至少包含 30 个句子再使用。这也是为什么很多实现会在句子数不足时给出警告或直接拒绝计算。2.2 多音节词怎么数音节切分的工程近似音节切分是 SMOG 实现里最容易翻车的地方。英语音节没有绝对精确的规则常见做法是用启发式规则近似。我一般会按这个顺序处理先把单词转小写去掉首尾非字母字符然后统计元音字母组a、e、i、o、u、y的连续段数量再减去末尾不发音的 e最后处理一些例外比如 “es”“ed” 结尾不额外计音节的情况。下面是一个可复用的音节计数函数function countSyllables(word) { // 转小写并去掉非字母字符 word word.toLowerCase().replace(/[^a-z]/g, ); if (word.length 3) return 1; // 短词直接算一个音节 // 去掉末尾不发音的 e word word.replace(/(?:[^laeiouy]es|ed|[^laeiouy]e)$/, ); word word.replace(/^y/, ); // 词首 y 不算元音 // 匹配连续元音组 const matches word.match(/[aeiouy]{1,2}/g); return matches ? matches.length : 1; }逻辑说明前三行做预处理把干扰字符清掉。word.length 3是一个经验阈值像 “the”“and” 这种短词直接返回 1避免规则误判。两个replace分别处理末尾 e 和词首 y 的情况。最后的正则[aeiouy]{1,2}把连续元音当作一个音节单位比如 “beau” 里的 “eau” 算一个。参数方面如果你处理的文本里有大量专有名词或缩写建议在调用前先做一次白名单过滤否则音节数会偏高。2.3 句子切分与完整计算流程句子切分比音节切分简单但也不能随便按句号 split。常见做法是用正则匹配句末标点同时排除小数点和缩写点。下面是一个完整的 SMOG 计算函数function calculateSMOG(text) { // 按句末标点切分排除小数点和常见缩写 const sentences text .replace(/([.?!])\s*(?[A-Z])/g, $1|) .split(|) .filter(s s.trim().length 0); const sentenceCount sentences.length; if (sentenceCount 30) { console.warn(句子数少于 30SMOG 结果可能不准确); } // 提取所有单词 const words text.toLowerCase().match(/[a-z]/g) || []; // 统计多音节词三个及以上音节 const polySyllables words.filter(w countSyllables(w) 3).length; // 套用 SMOG 公式 const smog 1.0430 * Math.sqrt(polySyllables * (30 / sentenceCount)) 3.1291; return { smogIndex: Math.round(smog * 10) / 10, sentenceCount, polySyllableCount: polySyllables, wordCount: words.length }; }逻辑说明句子切分用了一个替换技巧先把句末标点后面跟大写字母的位置插入分隔符再按分隔符切分这样能避开 “3.14” 这种小数点。sentenceCount 30的警告是必须的否则用户会拿到一个看起来合理但实际偏差很大的数值。多音节词统计调用了前面的countSyllables阈值设为 3。最后公式里的常数 1.0430 和 3.1291 是原公式的固定系数不要改。返回结果里带上句子数、多音节词数和总词数方便排查。2.4 结果解读SMOG 指数对应什么阅读水平算出来的 SMOG 指数是一个数值通常按四舍五入取整后对应年级水平。下面这张表是常见的对照关系SMOG 指数对应年级水平典型读物5-6小学高年级儿童故事、简单说明7-8初中青少年小说、科普短文9-10高中新闻评论、一般技术文档11-12高中毕业学术入门、专业博客13-15大学学术论文、法律文书16研究生及以上专业期刊、技术标准注意这个对照是英文语境下的经验值。如果你拿它去测中文文本多音节词的定义完全不适用结果没有参考意义。SMOG 公式的设计对象是英文这一点在选型时要先确认。3. 把 SMOG 接进项目从安装到批量检测的完整操作3.1 环境准备与模块引入这个资源是一个 JavaScript 模块可以在 Node.js 环境或浏览器端使用。如果你用 npm 管理依赖常见做法是直接安装到项目里如果只是临时测一段文本也可以把核心函数复制到本地文件里跑。我一般会先建一个独立目录避免污染现有项目mkdir smog-test cd smog-test npm init -y npm install smog-formula安装完成后在脚本里引入const smog require(smog-formula); // 或者 ES Module 方式 // import smog from smog-formula;参数说明npm init -y生成默认的 package.json省去交互。npm install smog-formula会把模块装进 node_modules。如果你的项目用的是 pnpm 或 yarn把 install 命令替换成对应工具的写法即可模块本身不依赖特定包管理器。3.2 单段文本检测最小可运行示例先拿一段英文文本跑通流程确认环境没问题const smog require(smog-formula); const sampleText The quick brown fox jumps over the lazy dog. This sentence is simple. However, the implementation of internationalization frameworks often requires significant consideration of multiple architectural perspectives. Developers must evaluate the trade-offs between performance and maintainability. ; const result smog({ text: sampleText, minSentences: 30 // 低于此值会触发警告 }); console.log(SMOG 指数:, result.smogIndex); console.log(句子数:, result.sentenceCount); console.log(多音节词数:, result.polySyllableCount);逻辑说明调用时传入文本和minSentences参数。minSentences默认是 30如果你明确知道文本较短且只想要一个粗略参考可以调低但结果的可信度会下降。输出里smogIndex是最终指数另外两个字段用于验证中间步骤是否合理。如果polySyllableCount明显偏高先检查文本里是不是混入了大量缩写或代码片段。3.3 批量检测遍历文件目录并输出报告实际项目里更常见的是批量检测一批文档。下面这个脚本会遍历指定目录下的所有.txt文件逐个计算 SMOG 指数并输出汇总const fs require(fs); const path require(path); const smog require(smog-formula); const targetDir ./docs; function analyzeDirectory(dir) { const files fs.readdirSync(dir).filter(f f.endsWith(.txt)); const report []; for (const file of files) { const content fs.readFileSync(path.join(dir, file), utf-8); const result smog({ text: content, minSentences: 30 }); report.push({ file, smogIndex: result.smogIndex, sentences: result.sentenceCount, polySyllables: result.polySyllableCount }); } // 按 SMOG 指数降序排列最难的排前面 report.sort((a, b) b.smogIndex - a.smogIndex); console.table(report); return report; } analyzeDirectory(targetDir);逻辑说明readdirSync同步读取目录适合文件数量不多的场景。每个文件独立调用 SMOG 计算结果推进report数组。最后按指数降序排列方便一眼看出哪些文档最难读。console.table在 Node.js 里能直接输出表格省去手动格式化。参数方面targetDir改成你的实际目录路径即可如果文件编码不是 UTF-8需要在readFileSync里指定对应编码。3.4 把结果写进 CI自动化可读性检查如果你想让可读性检查变成流程的一部分可以在 CI 脚本里加一个阈值判断。比如规定所有面向用户的文档 SMOG 指数不得超过 12超过就报错退出const MAX_SMOG 12; function checkReadability(report) { const violations report.filter(r r.smogIndex MAX_SMOG); if (violations.length 0) { console.error(以下文档可读性不达标); violations.forEach(v { console.error( ${v.file}: SMOG ${v.smogIndex} (上限 ${MAX_SMOG})); }); process.exit(1); } console.log(所有文档可读性检查通过); } // 接在 analyzeDirectory 之后调用 checkReadability(analyzeDirectory(targetDir));逻辑说明MAX_SMOG是阈值参数按你的目标读者群体调整。filter筛出超标的文档如果有就打印文件名和实际指数然后process.exit(1)让 CI 任务失败。这个模式可以直接嵌进 GitHub Actions、GitLab CI 或其他流水线里。注意阈值不要设得太死技术文档天然会比营销文案难按文档类型分开设阈值更合理。4. 避坑与排查SMOG 计算里最容易翻车的五个地方4.1 句子数不足 30 却直接采信结果现象一段只有五六句话的文本算出来 SMOG 指数是 8看起来挺合理但实际读者反馈还是难懂。原因SMOG 公式的归一化基准是 30 个句子句子数远低于 30 时多音节词数的微小波动会被放大结果不稳定。解决在代码里强制检查句子数低于 30 时要么拒绝输出要么在结果里附带明确的置信度警告。我一般会在返回对象里加一个reliable: sentenceCount 30字段让调用方自己决定怎么处理。4.2 音节计数把缩写和代码当成多音节词现象一段技术文档里包含 “API”“HTTP”“JSON” 这类缩写算出来的多音节词数异常高SMOG 指数虚高。原因音节计数函数按元音组来数缩写里没有标准元音结构容易被误判。解决在统计前先做一轮过滤把全大写且长度小于等于 5 的词、以及包含数字的词排除掉。常见做法是维护一个白名单或者用正则/\b[A-Z]{2,}\b/先标记出来再决定是否计入。4.3 句子切分把小数点和缩写点当成句末现象文本里有 “version 3.14” 或 “Dr. Smith” 这样的内容句子数被多算SMOG 指数偏低。原因简单的按句号切分无法区分句末点和非句末点。解决用更精细的正则要求句末标点后面跟空格和大写字母或者维护一个常见缩写列表Dr.、Mr.、etc.在切分前先做替换。上面 2.3 节里的切分逻辑已经处理了小数点后跟大写字母的情况但缩写列表需要按你的文本特点补充。4.4 拿 SMOG 去测中文或其他非英文文本现象把一段中文文本丢进去算出来一个数值但完全不知道对应什么水平。原因SMOG 公式的多音节词定义基于英文音节结构中文没有音节切分的概念公式的输入变量根本不成立。解决明确 SMOG 只适用于英文文本。如果你需要评估中文可读性得换用针对中文的指标比如基于字频、词频或句长的模型。这个资源本身不解决中文场景选型时要先确认这一点。4.5 忽略文本预处理导致结果波动现象同一篇文档两次运行结果不一样。原因文本里混入了 Markdown 标记、HTML 标签或多余空白影响了单词和句子的切分。解决在调用 SMOG 之前先做一轮清洗去掉 Markdown 语法符号、HTML 标签、连续空白和换行符。常见做法是先用正则把[^]和[#*_[]] 这类字符替换掉再传给计算函数。清洗步骤不要省否则结果没有可比性。5. 进阶技巧用 SMOG 做版本对比与写作反馈SMOG 不只是一个一次性检测工具它还能用来做版本对比。我习惯在修改文档前后各跑一次把两次的 SMOG 指数和多音节词数拉出来对比看看改动到底有没有降低阅读难度。下面这个函数接收两个版本的文本输出差异报告function compareVersions(oldText, newText) { const oldResult smog({ text: oldText, minSentences: 30 }); const newResult smog({ text: newText, minSentences: 30 }); const diff { smogChange: (newResult.smogIndex - oldResult.smogIndex).toFixed(1), polySyllableChange: newResult.polySyllableCount - oldResult.polySyllableCount, sentenceChange: newResult.sentenceCount - oldResult.sentenceCount }; console.log(SMOG 变化:, diff.smogChange 0 ? ${diff.smogChange} : diff.smogChange); console.log(多音节词变化:, diff.polySyllableChange); console.log(句子数变化:, diff.sentenceChange); return diff; }逻辑说明分别计算两个版本的指标然后做差。smogChange为正说明改版后更难读了为负说明可读性提升。polySyllableChange能帮你定位问题——如果 SMOG 上升主要来自多音节词增加那就去检查新引入了哪些长词。sentenceChange则反映句子拆分或合并的情况。参数方面两个文本的句子数都要尽量接近 30 以上否则差异值本身就不稳定。另一个实用技巧是把 SMOG 指数和具体段落绑定。不要只算整篇文档的总分而是按段落分别计算找出最难读的那几段重点修改。做法很简单按空行切分段落每段单独调用 SMOG然后按指数排序。这样你能快速定位到“拖后腿”的段落而不是对着一个总分干瞪眼。还有一个边界要注意SMOG 对文本长度敏感太短的段落算出来的指数波动很大。我一般会跳过少于 5 个句子的段落或者把它们合并后再算。如果你在做自动化检查建议在报告里标注每个段落的句子数让读者自己判断可信度。从那以后我每次写完面向用户的文档都会先跑一遍 SMOG把指数超过 12 的段落挑出来重写再对比修改前后的数值。这个习惯帮我省掉了不少“看不懂”的反馈。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询