在字符串中将单词首字母大写

228

如何最好地将字符串中的单词大写?


73
如果是用于展示,可以使用 CSS 的 text-transform: capitalize; - kennytm
4
这是用来设置DOM元素的"title"属性,不需要使用CSS :) - vsync
1
此外,我已经问过这个问题,虽然我知道解决方案,但是因为我尝试在这个网站上寻找它并没有找到一个合适的解决方案,所以为了记录而添加了它。 - vsync
2
@KennyTM:text-transform并不会真正将表单字段的值大写,所有的值都会以大写形式呈现,但发送到服务器的值仍然是原样。 - Marco Demaio
8
@Marco:是的,这就是为什么我说“如果是用来展示”的原因。 - kennytm
显示剩余7条评论
21个回答

330
/**
 * Capitalizes first letters of words in string.
 * @param {string} str String to be modified
 * @param {boolean=false} lower Whether all other letters should be lowercased
 * @return {string}
 * @usage
 *   capitalize('fix this string');     // -> 'Fix This String'
 *   capitalize('javaSCrIPT');          // -> 'JavaSCrIPT'
 *   capitalize('javaSCrIPT', true);    // -> 'Javascript'
 */
const capitalize = (str, lower = false) =>
  (lower ? str.toLowerCase() : str).replace(/(?:^|\s|["'([{])+\S/g, match => match.toUpperCase());
;
  • 修复了Marco Demaio的解决方案,其中第一个带有空格前缀的字母未大写。
capitalize(' javascript'); // -> ' Javascript'
  • 可以处理国家符号和重音字母。
capitalize('бабушка курит трубку');  // -> 'Бабушка Курит Трубку'
capitalize('località àtilacol')      // -> 'Località Àtilacol'
  • 可以处理引号和大括号。
capitalize(`"quotes" 'and' (braces) {braces} [braces]`);  // -> "Quotes" 'And' (Braces) {Braces} [Braces]

4
正则表达式的作用是:“获取字符串开头(^)或在任何空白字符(\s)后面的所有非空白字符(\S),并将它们转换为大写字母。” - disfated
3
稍作修改以处理大写字符串 :)** String.prototype.capitalize = function() { return this.toLowerCase().replace(/(?:^|\s)\S/g, function(a) { return a.toUpperCase(); }); }; ** - SuryaPavan
1
请不要更改现有对象的原型。 - Ascherer
1
@Dr.X,请看附加组件,'CHECK THIS OUT'.capitalize(true) -> "Check This Out"。注意true参数。 - disfated
1
@SeaWarrior404,你是对的,我用es6语法更新了我的答案,并添加了jsdoc和一些标点符号处理。 - disfated
显示剩余8条评论

279

使用ES6的箭头函数,将字符串中的单词首字母大写的最短实现方式如下:

'your string'.replace(/\b\w/g, l => l.toUpperCase())
// => 'Your String'

ES5 兼容实现:

'your string'.replace(/\b\w/g, function(l){ return l.toUpperCase() })
// => 'Your String'

该正则表达式基本上匹配给定字符串中每个单词的第一个字母,并仅将该字母转换为大写:

  • \b匹配单词边界(单词的开头或结尾);
  • \w匹配以下元字符[a-zA-Z0-9]。

对于非ASCII字符,请参考此解决方案

'ÿöur striñg'.replace(/(^|\s)\S/g, l => l.toUpperCase())

此正则表达式匹配给定字符串中前导空格和每个非空白字母,并将仅该字母转换为大写:

  • \s 匹配任何空白字符
  • \S 匹配任何非空白字符
  • (x|y) 匹配指定的任意一个选项

在这里,也可以使用非捕获组,如下所示/(?:^|\s)\S/g尽管我们的正则表达式中的g标志不会捕获子组。


1
你能在答案中解释一下正则表达式是如何工作的吗?(每个部分的含义) - vsync
2
如果解释在答案中而不是评论中,我会选择它作为答案。 - vsync
3
似乎无法处理北欧字符ä、ö和å。例如,päijät-häme 变成了 PäIjäT-HäMe - Markus Meskanen
2
这个解决方案不适用于包含变音符号/非拉丁字符的国际内容。例如,EisbäRen 就是一个结果。 - Daniel B.
4
@MarkusMeskanen提供的例子应更改为Päijät-Häme,但在Chrome浏览器中空格不包括破折号(-),所以名称的第二部分没有大写。可以使用/(^|\s|-)\S/g修复。 - MiRin
显示剩余5条评论

38
function capitalize(s){
    return s.toLowerCase().replace( /\b./g, function(a){ return a.toUpperCase(); } );
};

capitalize('this IS THE wOrst string eVeR');

输出结果: "This Is The Worst String Ever"

更新:

看起来这个解决方案比我的更好: https://dev59.com/7HE95IYBdhLWcg3wY85l#7592235


1
注意,它似乎错误地将重音字母也大写了,请查看我的答案:https://dev59.com/7HE95IYBdhLWcg3wY85l#5678673 我还原型化了它。 - Marco Demaio
10
我不喜欢原型制作,因为如果其他人也在原型制作字符串时使用相同的名称,就有可能导致冲突。 - vsync

16

提供者vsync的答案在输入字符串中只要没有重音字母就可以正常工作

我不知道原因,但显然regexp中的 \ b 也匹配重音字母(在IE8和Chrome上测试),因此像"località"这样的字符串会被错误地大写转换为"LocalitÀ" (因为regexp认为它是一个单词分界符而将字母à转成了大写)

一个更通用的函数,也适用于重音字母,如下所示:

String.prototype.toCapitalize = function()
{ 
   return this.toLowerCase().replace(/^.|\s\S/g, function(a) { return a.toUpperCase(); });
}

您可以像这样使用它:

alert( "hello località".toCapitalize() );

1
" javascript".toCapitalize() -> " javascript" - disfated
2
敬启者:回答链接https://dev59.com/7HE95IYBdhLWcg3wY85l#7592235 现在是此处最佳答案。 - Marco Demaio

10

一个简单、直接(非正则表达式)的解决方案:

const capitalizeFirstLetter = s => 
  s.split(' ').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')
  1. 通过空格分隔符将字符串拆分为单词数组
  2. 将每个单词分解为首字符 + 单词中其余字符
  3. 将首字母转换为大写,其余部分保持不变
  4. 使用空格重新将数组连接为字符串

我认为你可以避免迭代,只需执行 function capitalize(s){ let _s = s.trim().toLowerCase(); return _s.charAt(0).toUpperCase() + _s.slice(1) } - miguelps

8

Ivo的回答很好,但我不喜欢匹配\w,因为0-9和A-Z没有大写的必要。我们可以忽略它们,只匹配a-z。

'your string'.replace(/\b[a-z]/g, match => match.toUpperCase())
// => 'Your String'

输出结果相同,但我认为自文档代码更加清晰。


2
@vsync 看起来有点苛刻。这是对被接受答案的优化。/\b\w/g 对于非英文字母也会失败。并不是每个人都处理 Unicode 字符,这将帮助那些不想处理它们的人。 - Big Money

5

既然大家已经给出了你所要求的JavaScript答案,我想提供的是CSS属性text-transform: capitalize可以完美地实现这一点。

我明白这可能不是你所要求的 - 因为你没有告诉我们你运行它的上下文 - 但如果只是为了展示,我肯定会选择CSS替代方案。


KennyTM 比你更快,他在问题部分留言了。 :-) - Buhake Sindi
是的,我知道这个CSS属性,但我需要它用于DOM元素的标题属性,而且它与CSS毫无关系,正如你所知道的。 - vsync

5

我的解决方案:

String.prototype.toCapital = function () {
    return this.toLowerCase().split(' ').map(function (i) {
        if (i.length > 2) {
            return i.charAt(0).toUpperCase() + i.substr(1);
        }

        return i;
    }).join(' ');
};

例子:

'álL riGht'.toCapital();
// Returns 'Áll Right'

尝试几种方法,找到最有效的解决方案并尊重名称的重音。https://jsbench.me/urjeu9wvql - nasatome
这个不起作用:'a áAA. bb . bbb .cc .d'.toCapital(); => a Áaa. bb . Bbb .cc .d - vsync
我设置了不考虑长度小于2个字母的单词,例如“of”、“as”。 - Erick Tatsui

4

使用JavaScript和html

String.prototype.capitalize = function() {
  return this.replace(/(^|\s)([a-z])/g, function(m, p1, p2) {
    return p1 + p2.toUpperCase();
  });
};
<form name="form1" method="post">
  <input name="instring" type="text" value="this is the text string" size="30">
  <input type="button" name="Capitalize" value="Capitalize >>" onclick="form1.outstring.value=form1.instring.value.capitalize();">
  <input name="outstring" type="text" value="" size="30">
</form>

基本上,你可以使用string.capitalize()函数,它将把每个单词的第一个字母大写。

来源:http://www.mediacollege.com/internet/javascript/text/case-capitalize.html


1
我不喜欢用这种方式进行原型设计,因为我的脚本有时会作为第三方嵌入到其他网站中,这可能会导致与“String”等全局对象混淆的麻烦...所以我更喜欢使用“函数”。 - vsync
1
这就是原型的优美之处(不是你下载的那个“Prototype”)。它是Javascript标准,并且在所有浏览器中都起作用。 - Buhake Sindi
我怀疑如果其他人已经原型化了自己的String.prototype.capitalize,那么我会意外地覆盖它,这可能会导致问题。 - vsync
1
@vsync,你可以通过以下方式进行检查。if (object.capitalize) {...} else {String.prototype.capitalize = function()....} 其中 object 的类型为 String。所以,这其实很简单。 - Buhake Sindi

4
约翰·雷西格(jQuery的创始人)将John Gruber编写的perl脚本移植到JavaScript中。此脚本以更智能的方式进行大写,例如不会将“of”和“and”等小词大写。
您可以在这里找到它:Title Capitalization in JavaScript

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