
本文介绍在不使用 replace() 的前提下,将字符串首尾及中间的连续空白字符统一处理为单个连字符的函数式实现方案,重点解决多空格、前后空格等边缘情况。
本文介绍在不使用 `replace()` 的前提下,将字符串首尾及中间的连续空白字符统一处理为单个连字符的函数式实现方案,重点解决多空格、前后空格等边缘情况。
在构建 URL 友好型 slug(如博客标题转路径)时,一个常见需求是:将任意含冗余空格的字符串(如 " Peter is Coming")标准化为小写、无多余空格、单词间以单个短横线(-)连接的形式,即 "peter-is-coming"。关键约束是禁用 replace() 方法,需依赖 trim()、split()、join() 等纯函数式操作完成。
核心难点在于:原始代码中逐字符 split("") + filter() 的方式无法区分“单个空格”与“连续空格”,导致 "is Coming" 被转为 "is--coming"。正确解法应按空白序列整体切分,而非按字符处理。
✅ 推荐方案(简洁高效,符合函数式编程思想):
const urlSlug = (title) => console.log(
title.trim().toLowerCase().split(/\s+/).join("-")
);
该方案三步完成:
- trim() —— 移除首尾空白;
- toLowerCase() —— 统一小写;
- split(/\s+/) —— 使用正则 /\s+/ 将一个或多个连续空白字符作为分隔符,确保 " "、"\t\n" 等均被视作单一断点,返回干净的单词数组;
- join("-") —— 用单个 - 连接所有单词。
? 注意事项:
- 正则 /\s+/ 比 / /g 更健壮,可同时匹配空格、制表符、换行符等所有 Unicode 空白;
- 避免使用 split(" ")(仅按单空格切分),否则 "a b" 会得到 ["a", "", "b"],引入空字符串;
- 若需返回字符串而非直接 console.log,请将最后一行改为 return title.trim().toLowerCase().split(/\s+/).join("-");;
- 此方案时间复杂度 O(n),无显式循环,完全符合函数式范式。
? 扩展思考:若需兼容更复杂的清洗逻辑(如过滤空项、移除标点),可在 split() 后链式调用 .filter(Boolean) 确保无空字符串,例如:
title.trim().toLowerCase().split(/\s+/).filter(Boolean).join("-")
综上,抓住「按空白序列切分」这一本质,即可优雅、高效、可读性强地解决多空格 slug 生成问题。










