使用JavaScript将字符串转换为标题大小写

779

有没有一种简单的方法将字符串转换为标题格式?例如,john smith 变成 John Smith。我不想要像John Resig的解决方案那样复杂的东西,只是(希望)一种一两行代码就能实现的方法。


1
有许多方法,我们有一些性能统计数据吗? - theAnubhav
1
@theAnubhav 是的,我们现在有一个基准 - Ulysse BN
2
到了2022年,浏览器仍然没有本地功能来执行此操作。 - Sơn Trần-Nguyễn
1
这种大小写格式完全取决于语言/地点/文化。 - James Moore
我希望解决方案的一个测试用例是“Comhrá i mBÁC le Seán Nguyen” - 祝你好运!基本上,计算机可以执行称为“标题大小写”的操作的想法可能是没有希望的,即使给定了大量的机器学习资源。 - James Moore
69个回答

4
我们在办公室进行了讨论,认为试图自动纠正人们输入姓名的方式存在可能的问题。我们找到了几种情况,不同类型的自动大写字母都会出现问题,而这些只是针对英文名字的情况,每种语言都有其自己的复杂性。
以下是大写首字母存在的问题:
• IBM等缩写无法输入,会变成Ibm。
• 姓氏McDonald会变成Mcdonald,而姓氏MacDonald也是一样。
• Marie-Tonks这样的双重姓氏会变成Marie-tonks。
• O'Connor这样的名字会变成O'connor。
虽然你可以编写自定义规则来处理大多数问题,但仍会出现缩写问题,而且还会遇到新问题:
• 添加用于修复MacDonald等名称的规则将破坏Macy这样的名称,将其变成MacY。
唯一我们想到的从不出错的解决方案就是将每个字母都大写,这是一个粗暴的方法,似乎DBS也在使用这种方法。
因此,如果要自动化这个过程,除非拥有每个名称和单词及其应该大写的方式的字典,否则几乎不可能做到。如果您没有覆盖所有情况的规则,请不要使用它,因为这只会让用户感到恼怒,并促使希望正确输入姓名的人去其他地方。

你可以测试输入字符串是否已经被正确地大小写化,只有在它不是这样的情况下(例如全部小写或全部大写),才使用你最好的算法来更改大小写。 - dan-man
我同意。这就是为什么国际组织发布的文件中,人名都会使用大写字母,比如护照和身份证等。将其转换为大写字母更简单且非常准确。 - undefined

4
采用“lewax00”方案后,我创建了这个简单的解决方案,强制让以空格或以“w”作为单词开头的字符均被替换为“w”,但无法删除多余的中间空格。

"SOFÍA vergara".toLowerCase().replace(/\b(\s\w|^\w)/g, function (txt) { return txt.toUpperCase(); });

结果是“索菲亚·维加拉”。

4

将单词转换为标题大小写的简单方法

使用“切片”方法和字符串连接

str.slice(0, 1).toUpperCase() + str.slice(1, str.length)

*如果要将单词其余部分转换为小写,请在结尾添加.toLowerCase()

使用ES6 Spread Operator、Map和Join

[...str].map((w, i) => i === 0 ? w[0].toUpperCase() : w).join('')

4

我的一行代码解决方案:

String.prototype.capitalizeWords = function() {
    return this.split(" ").map(function(ele){ return ele[0].toUpperCase() + ele.slice(1).toLowerCase();}).join(" ");
};

然后,您可以在任何字符串上调用capitalizeWords()方法。例如:
var myS = "this actually works!";
myS.capitalizeWords();

>>> This Actually Works

我的另一种解决方案:

function capitalizeFirstLetter(word) {
    return word[0].toUpperCase() + word.slice(1).toLowerCase();
}
String.prototype.capitalizeAllWords = function() {
    var arr = this.split(" ");
    for(var i = 0; i < arr.length; i++) {
        arr[i] = capitalizeFirstLetter(arr[i]);
    }
    return arr.join(" ");
};

然后,您可以在任何字符串上调用capitalizeWords()方法。例如:

var myStr = "this one works too!";
myStr.capitalizeWords();

>>> This One Works Too

基于 Greg Dean 答案的另一种解决方案:

function capitalizeFirstLetter(word) {
    return word[0].toUpperCase() + word.slice(1).toLowerCase();
}
String.prototype.capitalizeWords = function() {
    return this.replace(/\w\S*/g, capitalizeFirstLetter);
};

然后,您可以在任何字符串上调用capitalizeWords()方法。例如:
var myString = "yes and no";
myString.capitalizeWords()

>>> Yes And No

3
这是基于我的解决方案FreeCodeCamp的篝火“标题大小写”,它要求您首先将给定的字符串转换为全小写,然后将每个空格后面的字符转换为大写。
不使用正则表达式:
function titleCase(str) {
 return str.toLowerCase().split(' ').map(function(val) { return val.replace(val[0], val[0].toUpperCase()); }).join(' ');
}

3
您可以将第一个字符大写,并与剩余字符串连接起来。

let str = 'john smith';
let res = str.split(" ");
res.forEach((w, index) => {
    res[index] =  w.charAt(0).toUpperCase().concat(w.slice(1, w.length))
});
res = res.join(" ");
console.log(res);


3
使用正则表达式获取所有以单词边界\b[a-zA-Z]开头的字符\g,并应用.toUpperCase()

const textString = "Convert string to title case with Javascript.";
const converted = textString.replace(/\b[a-zA-Z]/g, (match) => match.toUpperCase());
console.log(converted)


使用“我是一个小茶壶”将会得到“我是一个小茶壶”。 - xGeo

3

var string = "tEsT"

string = string.toLowerCase() 
var output= string.charAt(0).toUpperCase() + string.slice(1)
console.log(output)
alert(output)

  
 var string = "tEsT"

 string = string.toLowerCase() 

 string.charAt(0).toUpperCase() + string.slice(1)
  • string.charAt(0) 返回字符串中索引为0的字符。
  • toUpperCase() 是一个方法,它返回一个字符串的大写形式。它应用于字符串的第一个字符,由charAt(0)返回。
  • string.slice(1) 返回一个新的字符串,从索引1开始(不包括索引0处的字符),直到字符串的末尾。
  • 最后,该表达式将 toUpperCase() 和 string.slice(1) 的结果连接起来,创建一个首字母大写的新字符串。

请解释一下你的建议与 https://dev59.com/WXVC5IYBdhLWcg3wvT7g#70546786 中给出的区别,因为那似乎是你只复制了核心代码行而没有任何解释的地方。 - Yunnosch
@Yunnosch添加了解释 - Zahid
你解释了代码。我想知道与旧的、得到赞同的问题相比,相关的区别是什么,因为它似乎提供了相同的核心解决方案。这里哪个更好?如果代码不是更好,甚至没有区别,那么你的帖子提供了什么额外的见解?你需要避免给人留下这样的印象:你只是从现有的得到赞同的答案中抄袭,试图偷取一些声望。或者你根本就没有费心阅读现有的答案。 - Yunnosch
1
抱歉 @Yunnosch,我没有从外部复制,如果您不同意,可以点击不喜欢,如果解决方案在您这边不起作用。 - Zahid

2
我的列表是基于三个快速搜索。一个是关于不应大写的单词列表,另一个是关于所有介词的完整列表。
最后一个搜索提出了一个建议,即长度为5个字母或更长的介词应该大写,这是我喜欢的。我的目的是进行非正式使用。我保留了“without”,因为它是“with”的明显对应物。
因此,它会将首字母缩写、标题的第一个字母以及大多数单词的第一个字母大写。
它不适用于全大写的单词。我想让它们保持原样。

function camelCase(str) {
  return str.replace(/((?:^|\.)\w|\b(?!(?:a|amid|an|and|anti|as|at|but|but|by|by|down|for|for|for|from|from|in|into|like|near|nor|of|of|off|on|on|onto|or|over|past|per|plus|save|so|than|the|to|to|up|upon|via|with|without|yet)\b)\w)/g, function(character) {
  return character.toUpperCase();
})}
    
console.log(camelCase('The quick brown fox jumped over the lazy dog, named butter, who was taking a nap outside the u.s. Post Office. The fox jumped so high that NASA saw him on their radar.'));


如果我想创建一个 toTitleCase() 方法,使其像“原生”的 toLowerCase() 一样适用于 str.toTitleCase(),你会怎么做? - Razvan Zamfir
@RazvanZamfir 你可以修改字符串 prototype。你可以这样做 String.prototype.toTitleCase = function() {...} https://www.codementor.io/@dhruvkumarjha/extending-the-javascript-string-prototype-f3o5xjia6 - Regular Jo

2

大家好,这里是我的答案。如果您的问题得到解决,请评论并点赞。

function toTitleCase(str) {
  return str.replace(
    /(\w*\W*|\w*)\s*/g,
    function(txt) {
    return(txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase())
    }
  ); 
}
<form>
  Input:
  <br /><textarea name="input" onchange="form.output.value=toTitleCase(this.value)" onkeyup="form.output.value=toTitleCase(this.value)"></textarea>
  <br />Output:
  <br /><textarea name="output" readonly onclick="select(this)"></textarea>
</form>


小心带有标记的单词。例如:cördoba 显示为 CöRdoba。 - Silvestre
感谢您的建议。我会在找到解决方案后更新我的答案。 - Soham Patel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接