You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现带例外规则且不修改原型的JS标题大小写转换方法

解决方案:不修改原型实现自定义标题大小写转换(支持例外规则)

如果严格不修改String原型,可以用工具函数实现;如果想要像.toLowerCase()一样的方法调用便捷性,也可以安全扩展原型(仅在方法不存在时添加,避免覆盖原有逻辑)。两种方案都支持自定义例外词,且保留原有的「次要单词非首尾时小写」规则。


方案一:工具函数(完全不修改原型)

实现代码

// 例外词映射:键为小写单词,值为预设的目标大小写形式
const casingExceptions = new Map();
// 初始化预设例外词
["cm", "DOE", "ft", "ID", "KC", "mm", "TV", "USA"].forEach(word => {
  casingExceptions.set(word.toLowerCase(), word);
});

// 次要单词列表(非首尾位置时强制小写)
const minorWords = new Set([
  "a", "an", "and", "as", "at", "but", "by", "for", 
  "from", "in", "into", "near", "nor", "of", "on", 
  "onto", "or", "the", "to", "with"
]);

// 核心转换函数
function toTitleCase(str) {
  if (typeof str !== 'string') return str;

  return str.replace(/[\w’'-]+/g, (match, index, fullStr) => {
    const lowerMatch = match.toLowerCase();

    // 优先匹配例外词,直接返回预设格式
    if (casingExceptions.has(lowerMatch)) {
      return casingExceptions.get(lowerMatch);
    }

    // 判断当前单词是否为字符串的首尾单词
    const isFirstWord = index === 0 || /^\s*$/.test(fullStr.slice(0, index));
    const isLastWord = index + match.length === fullStr.length || /^\s*$/.test(fullStr.slice(index + match.length));

    // 基础标题大小写转换
    let processedWord = match.charAt(0).toUpperCase() + match.slice(1).toLowerCase();

    // 非首尾的次要单词转为小写
    if (!isFirstWord && !isLastWord && minorWords.has(lowerMatch)) {
      processedWord = processedWord.toLowerCase();
    }

    return processedWord;
  });
}

使用方式

直接传入字符串调用:

const input = 'THE DOE IN THE USA DOESN’T USE THE UNIT CM.';
const output = toTitleCase(input);
console.log(output); // 输出:"The DOE in the USA Doesn’t Use the Unit cm."

补充例外词

后续需要添加新规则时,只需调用:

// 示例:添加"GDP"(全大写)和"kg"(全小写)
casingExceptions.set("gdp", "GDP");
casingExceptions.set("kg", "kg");

方案二:安全扩展原型(方法调用形式)

如果想要像原生方法一样直接在字符串实例上调用,且避免覆盖已有方法,可以在仅当toTitleCase不存在时扩展String原型:

实现代码

// 例外词映射
const casingExceptions = new Map();
["cm", "DOE", "ft", "ID", "KC", "mm", "TV", "USA"].forEach(word => {
  casingExceptions.set(word.toLowerCase(), word);
});

// 次要单词列表
const minorWords = new Set([
  "a", "an", "and", "as", "at", "but", "by", "for", 
  "from", "in", "into", "near", "nor", "of", "on", 
  "onto", "or", "the", "to", "with"
]);

// 安全扩展原型:仅当方法不存在时添加
if (!String.prototype.toTitleCase) {
  String.prototype.toTitleCase = function() {
    return this.replace(/[\w’'-]+/g, (match, index, fullStr) => {
      const lowerMatch = match.toLowerCase();

      if (casingExceptions.has(lowerMatch)) {
        return casingExceptions.get(lowerMatch);
      }

      const isFirstWord = index === 0 || /^\s*$/.test(fullStr.slice(0, index));
      const isLastWord = index + match.length === fullStr.length || /^\s*$/.test(fullStr.slice(index + match.length));

      let processedWord = match.charAt(0).toUpperCase() + match.slice(1).toLowerCase();

      if (!isFirstWord && !isLastWord && minorWords.has(lowerMatch)) {
        processedWord = processedWord.toLowerCase();
      }

      return processedWord;
    });
  };
}

使用方式

直接在字符串实例上调用:

const input = 'THE DOE IN THE USA DOESN’T USE THE UNIT CM.';
const output = input.toTitleCase();
console.log(output); // 输出:"The DOE in the USA Doesn’t Use the Unit cm."

补充例外词

同样通过casingExceptions.set()添加新规则:

casingExceptions.set("ceo", "CEO");
casingExceptions.set("ml", "ml");

核心逻辑说明

  1. 例外词处理:用Map存储小写单词到目标格式的映射,确保不管输入的例外词是全大写、全小写还是混合格式,都能准确替换为预设样式。
  2. 次要单词规则:通过判断单词在字符串中的位置,仅对非首尾的次要单词强制转为小写。
  3. 正则兼容性:使用/[\w’'-]+/g匹配包含撇号、连字符的单词,兼容Doesn’t这类特殊格式的词汇。

内容的提问来源于stack exchange,提问作者Mtullis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 00:05:41