如何在JavaScript中将字符串的首字母大写?


3756

如何使字符串的第一个字母大写,但不更改其他任何字母的大小写?

例如:

  • "this is a test" -> "This is a test"
  • "the Eiffel Tower" -> "The Eiffel Tower"
  • "/index.html" -> "/index.html"

12
Underscore有一个名为underscore.string的插件,其中包括此插件以及其他许多出色的工具。
亚伦

关于什么:return str.replace(/(\b\w)/gi,function(m){return m.toUpperCase();});
Muhammad Umer 2014年

110
更简单:string[0].toUpperCase() + string.substring(1)
dr.dimitru

6
`${s[0].toUpperCase()}${s.slice(1)}`
noego

([initial, ...rest]) => [initial.toUpperCase(), ...rest].join("")
49КонстантинВан

Answers:


5802

基本解决方案是:

function capitalizeFirstLetter(string) {
  return string.charAt(0).toUpperCase() + string.slice(1);
}

console.log(capitalizeFirstLetter('foo')); // Foo

修改了其他一些答案String.prototype(这个答案也曾经使用过),但是由于可维护性,我现在建议这样做(很难找出将函数添加到的位置prototype,如果其他代码使用相同的名称/浏览器,则可能导致冲突在将来添加具有相同名称的本机函数)。

...然后,当您考虑国际化时,这个问题还有很多,正如这个令人惊讶的好答案(以下所述)所示。

如果要使用Unicode代码点而不是代码单元(例如,在基本多语言平面之外处理Unicode字符),则可以利用String#[@iterator]与代码点一起使用的事实,并且可以使用toLocaleUpperCase正确的语言环境大写形式:

function capitalizeFirstLetter([ first, ...rest ], locale = navigator.language) {
  return [ first.toLocaleUpperCase(locale), ...rest ].join('');
}

console.log(capitalizeFirstLetter('foo')); // Foo
console.log(capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉")); // "𐐎𐐲𐑌𐐼𐐲𐑉" (correct!)
console.log(capitalizeFirstLetter("italya", 'tr')); // İtalya" (correct in Turkish Latin!)

有关更多国际化选项,请参见下面原始答案


9
在更多浏览器中对substring的理解要比对substr的理解多
mplungjan'7

6
添加到karim79-使它成为javascript的功能可能会过大,而无需进行函数包装就可以对变量执行相同的操作。我想使用函数会更清楚,但是使用它的本机会更复杂,为什么还要使用函数包装器使其复杂化?
罗斯

18
我们是否还应该降低大小写slice(1)?
hasen 2014年

177
否,因为OP给出了以下示例:the Eiffel Tower -> The Eiffel Tower。另外,该函数称为capitaliseFirstLetternot capitaliseFirstLetterAndLowerCaseAllTheOthers
ban-geoengineering

22
没人在乎OOP的重要规则吗?- 永远不要编辑您不拥有的对象?。顺便说一句,这种string[0].toUpperCase() + string.substring(1)
单线

1349

这是一种更加面向对象的方法:

String.prototype.capitalize = function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
}

您可以像下面这样调用该函数:

"hello world".capitalize();

预期输出为:

"Hello world" 

24
我喜欢这种解决方案,因为它就像Ruby,而且Ruby很不错!:)我将字符串的所有其他字母都小写,以使其与Ruby完全相同:return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
ma11hew28 2011年

164
在此Prototype.js后的世界中,建议不要更改或扩展本机对象。
瑞安

191
@rxgx-“不要扩展”的布格曼人现在已经死了(感谢上帝),人们正在把头从jSand中抽出来,意识到它只是一种语言功能。仅仅因为Prototype.js在短时间内扩展了Object本身,并不意味着扩展Natives是不好的。如果要为未知的使用者编写代码(例如在随机站点上运行的分析脚本),则不应该这样做,但除此之外,还可以。
csuwldcat 2012年

43
@csuwldcat如果正在使用的另一个库在不知情的情况下添加了自己的大写字母怎么办?不管Prototype.js是否做到,扩展原型都是不好的形式。使用ES6,内在函数将使您可以吃蛋糕也可以吃。我认为您可能会迷惑那些制造符合ECMASCRIPT规范的垫片的“笨蛋”。这些垫片非常好,因为添加了垫片的另一个库将以相同的方式实现它。但是,应避免添加自己的非规范内在函数。
贾斯汀·迈尔

43
扩展本地人是一种极端的坏习惯。即使您说“哦,我再也不会将此代码与其他任何东西一起使用”,您(或其他人)也可能会使用。然后他们将花三天的时间来找出一些奇怪的数学错误,因为有人扩展了Number.money()以处理与您的其他库稍有不同的货币。认真地说,我已经看到这是在一家大公司发生的,没有人花时间调试一下弄清楚本机原型的库开发者,这是不值得的。
phreakhead 2014年

573

在CSS中:

p:first-letter {
    text-transform:capitalize;
}

80
OP正在寻求JS解决方案。
Antonio Max

129
$('#mystring_id')。text(string).css('text-transform','capitalize');
DonMB

21
此外,这只会影响字符串的显示-不会影响实际值。例如,如果采用某种形式,则该值仍将按原样提交。
dmansfield'6

12
这个答案使我意识到CSS解决方案确实更适合我的工作。@dudewad:答案可能会否认这不是JS解决方案,但根据需要可能更合适。
joshden

58
对于大约80%的观众来说,这是最好的答案。不是答案的问题,但对问题来代替。
吉万

289

这是流行答案的简化版本,它通过将字符串视为数组来获得第一个字母:

function capitalize(s)
{
    return s[0].toUpperCase() + s.slice(1);
}

更新:

根据下面的评论,这在IE 7或更低版​​本中不起作用。

更新2:

为了避免出现undefined空字符串(请参见下面的@ njzk2的注释),您可以检查一个空字符串:

function capitalize(s)
{
    return s && s[0].toUpperCase() + s.slice(1);
}

23
这在IE <8中不起作用,因为那些浏览器不支持字符串索引。IE8本身支持它,但仅支持字符串文字,不支持字符串对象。
Mathias Bynens'2

52
谁在乎,IE7市场不到5%!那可能是您的gremma和grempa的旧机器。我说短代码FTW!
vsync 2012年

@MathiasBynens您知道这是否会影响任何较旧的非IE浏览器或仅影响IE7?如果2014年没有其他浏览器会受到索引字符串文字的影响,那应该没问题。:)
hexalys 2014年

3
@vsync我只是说,根据您的用户人口统计,有时(尽管随着我们过去2014和以后的情况越来越少),支持IE7之类的旧浏览器是有利可图的……
joshuahedlund 2014年

2
@ njzk2处理空字符串,您可以更新为:return s && s[0].toUpperCase() + s.slice(1);
joelvh 2014年

187

如果您对发布的几种不同方法的性能感兴趣:

这是基于此jsperf测试的最快方法(从最快到最慢的顺序)。

如您所见,在性能方面,前两种方法本质上是可比的,而在性能方面进行更改String.prototype是迄今为止最慢的。

// 10,889,187 operations/sec
function capitalizeFirstLetter(string) {
    return string[0].toUpperCase() + string.slice(1);
}

// 10,875,535 operations/sec
function capitalizeFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

// 4,632,536 operations/sec
function capitalizeFirstLetter(string) {
    return string.replace(/^./, string[0].toUpperCase());
}

// 1,977,828 operations/sec
String.prototype.capitalizeFirstLetter = function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
}

在此处输入图片说明


1
似乎初始化代码也没有什么不同:jsperf.com/capitalize-first-letter-of-string/2
user420667

5
注意为好,在更换.slice(1)使用.substr(1)将进一步提高性能。
Przemek

1
合理考虑。请注意,在许多情况下,性能下降甚至不会引起注意:即使是“最慢”的方法,也可以在10毫秒内处理19k字符串。因此,为您选择最舒适的一种。
引用埃迪

1
如果有人好奇(像我一样)在过去四年中性能如何提高,那么2018年款Macbook Pro的第三项功能的运算/秒为135,307,869,因此快了12.4倍。
卡洛·菲尔德

151

在另一种情况下,我需要将其首字母大写,将其余字母小写。以下情况使我更改了此功能:

//es5
function capitalize(string) {
    return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
}
capitalize("alfredo")  // => "Alfredo"
capitalize("Alejandro")// => "Alejandro
capitalize("ALBERTO")  // => "Alberto"
capitalize("ArMaNdO")  // => "Armando"

// es6 using destructuring 
const capitalize = ([first,...rest]) => first.toUpperCase() + rest.join('').toLowerCase();

1
“ ...但不更改其他任何字母的大小写”。这不是OP提出的问题的正确答案。
卡洛斯·穆尼奥斯

2
@CarlosMuñoz,如果您读了开头的句子,他说这是针对另一种情况的。
TMH 2014年

3
@TomHart这就是为什么它不是该问题的解决方案的原因。它应该是评论或其他问题和答案
CarlosMuñoz14年

15
我确实同意你的看法,但是我可以看到很多人最终都在做这个答案。
TMH 2014年

74

这是2018 ECMAScript 6+解决方案

const str = 'the Eiffel Tower';
const newStr = `${str[0].toUpperCase()}${str.slice(1)}`;
console.log('Original String:', str); // the Eiffel Tower
console.log('New String:', newStr); // The Eiffel Tower


5
.slice()慢于.substring()str[0]undefined用于一个空字符串,并使用模板文字加入在这里8个字符的两所部分介绍,而+将只介绍3.
Przemek

4
我的答案Prz的目的是展示ES6支持的新功能,特别是模板文字,其他文章中未提及。StackOverflow的想法是为搜索者提供“选项”。如果他们的应用程序需要额外节省的毫秒数,他们可以采用此答案中描述的模板文字的概念,并将其与诸如Substring v。Slice之类的微速增强功能相结合。我的答案也不包含任何单元测试,这表明您永远不应直接复制粘贴StackOverflow答案。我认为开发人员会接受我的答案并对其进行调整。
Sterling Bourne

您在这里使用模板文字不会获得任何好处,${}只会增加噪音。const newStr = str[0].toUpperCase() + str.slice(1);更容易阅读。
鲍里斯(Boris)

1
然后同意不同意更容易阅读的内容。
斯特恩·伯恩

67

如果您已经(或正在考虑)使用lodash,则解决方案很简单:

_.upperFirst('fred');
// => 'Fred'

_.upperFirst('FRED');
// => 'FRED'

_.capitalize('fred') //=> 'Fred'

查看他们的文档:https : //lodash.com/docs#capitalize

_.camelCase('Foo Bar'); //=> 'fooBar'

https://lodash.com/docs/4.15.0#camelCase

_.lowerFirst('Fred');
// => 'fred'

_.lowerFirst('FRED');
// => 'fRED'

_.snakeCase('Foo Bar');
// => 'foo_bar'

Vanilla js的第一个大写字母:

function upperCaseFirst(str){
    return str.charAt(0).toUpperCase() + str.substring(1);
}

11
我认为应该首选Vanilla Js,因为大多数人不会下载整个框架只是为了大写字符串。
GGG 2015年

7
到目前为止,在我所有的项目中,我从未使用过lodash。别忘了,大多数google使用者都会在此页面结束,列出框架作为替代方法很好,但不是主要答案。
GGG

2
由于其他答案都使用vanilla js,因此很高兴有这样的答案,因为我们很多人都使用lodash / underscore。
罗曼

1
不是正确的答案,因为OP现在要求使用Javascript(而不是Javascript库)来执行此操作,Javascript库会将整个库作为项目的依赖项导入。不要使用它。
dudewad

1
OP的问题在我回答的结尾处是香草。
chovy

62

将字符串中所有单词的首字母大写:

function ucFirstAllWords( str )
{
    var pieces = str.split(" ");
    for ( var i = 0; i < pieces.length; i++ )
    {
        var j = pieces[i].charAt(0).toUpperCase();
        pieces[i] = j + pieces[i].substr(1);
    }
    return pieces.join(" ");
}

14
重新阅读问题:我想将字符串的第一个字符大写,但不更改其他任何字母的大小写。
JimmyPena 2011年

2
我知道我做到了 我要加一件事,以防整个字符串以大写字母开头:pieces [i] = j + Pieces [i] .substr(1).toLowerCase();
Malovich 2012年

4
这种情况的另一种解决方案:函数capitaliseFirstLetters(s){return s.split(“”).map(function(w){return w.charAt(0).toUpperCase()+ w.substr(1)))。join (“”)}如果未将其放入函数中,则可以是一个很好的单行代码。
路加·钱

首先将整个字符串小写会更好
Magico

除了此功能不能回答问题之外,它实际上也过于复杂。s => s.split(' ').map(x => x[0].toUpperCase() + x.slice(1)).join(' ')
OverCoder

48

我们可以用我最RegExp喜欢的一个获得第一个角色,看起来像一个可爱的笑脸:/^./

String.prototype.capitalize = function () {
  return this.replace(/^./, function (match) {
    return match.toUpperCase();
  });
};

对于所有咖啡迷:

String::capitalize = ->
  @replace /^./, (match) ->
    match.toUpperCase()

...对于所有认为有更好方法的人,而无需扩展本机原型:

var capitalize = function (input) {
  return input.replace(/^./, function (match) {
    return match.toUpperCase();
  });
};

2
有一种更好的方法,而不修改String原型。
Big McLargeHuge 2013年

2
@ davidkennedy85当然可以!但这是简单的方法,而不是最好的方法... ;-)
yckart

亲爱的洛迪,这个问题有百万答案!您的解决方案在es6中看起来更好。'Answer'.replace(/^./, v => v.toLowerCase())
stwilz


45

如果您使用underscore.jsLo-Dash,则underscore.string库提供字符串扩展名,包括大写:

_.capitalize(string)将字符串的首字母转换为大写。

例:

_.capitalize("foo bar") == "Foo bar"

3
3.0.0开始,Lo-Dash默认情况下具有此字符串方法。就像此答案中所述:_.capitalize("foo") === "Foo"
bardzusny 2015年

还有一些有用的underscore.js函数称为humanize。它将带下划线,驼色或反斜线的字符串转换为人性化的字符串。还删除开头和结尾的空格,并删除后缀'_id'。
Stepan Zakharov,2015年

1
从版本4 *开始,Lodash还要每隔一个字母小写一次(),请注意!
Igor Loskutov '16

45
String.prototype.capitalize = function(allWords) {
   return (allWords) ? // if all words
      this.split(' ').map(word => word.capitalize()).join(' ') : //break down phrase to words then  recursive calls until capitalizing all words
      this.charAt(0).toUpperCase() + this.slice(1); // if allWords is undefined , capitalize only the first word , mean the first char of the whole string
}

然后:

 "capitalize just the first word".capitalize(); ==> "Capitalize just the first word"
 "capitalize all words".capitalize(true); ==> "Capitalize All Words"

更新2016年11月(ES6),仅用于乐趣:

const capitalize = (string = '') => [...string].map(    //convert to array with each item is a char of string by using spread operator (...)
    (char, index) => index ? char : char.toUpperCase()  // index true means not equal 0 , so (!index) is the first char which is capitalized by `toUpperCase()` method
 ).join('')                                             //return back to string

然后 capitalize("hello") // Hello


3
我认为这是一个糟糕的解决方案,原因有两个:修改基本体的原型是一个坏主意。如果规范发生变化,并且他们决定选择“大写”作为新的原型属性名称,则您正在破坏核心语言功能。此外,选择的方法名称很差。乍一看,我认为这将使整个字符串大写。使用更具描述性的名称(例如PHP的ucFirst或类似名称)可能是一个更好的主意。
dudewad

ES6的另一个答案更简单:const capitalize = ([first,...rest]) => first.toUpperCase() + rest.join('').toLowerCase();
Dan Dascalescu

44

最短的 3个解决方案,当sstring 为时处理1和2个情况""null并且undefined

 s&&s[0].toUpperCase()+s.slice(1)        // 32 char

 s&&s.replace(/./,s[0].toUpperCase())    // 36 char - using regexp

'foo'.replace(/./,x=>x.toUpperCase())    // 31 char - direct on string, ES6


42

仅CSS

p::first-letter {
  text-transform: uppercase;
}
  • 尽管被调用了::first-letter,它仍然适用于第一个字符,即在使用string的情况下%a,该选择器将适用于大写字母%a因此不会大写。
  • 在IE9 +或IE5.5 +中,仅使用一个冒号(:first-letter)支持旧式表示法。

ES2015单缸

由于答案很多,但ES2015中没有一个答案可以有效解决原始问题,因此我提出了以下解决方案:

const capitalizeFirstChar = str => str.charAt(0).toUpperCase() + str.substring(1);

备注

  • parameters => function就是所谓的箭头功能
  • 我使用name capitalizeFirstChar而不是capitalizeFirstLetter,因为OP并不要求使用代码来大写整个字符串中的首个字母,而是首个字符(当然,如果是字母)。
  • const使我们能够声明capitalizeFirstChar为常量,这是需要的,因为作为程序员,您应始终明确声明您的意图。
  • 在我执行的基准测试中,string.charAt(0)和之间没有显着差异string[0]。但是请注意,那string[0]将是undefined空字符串,因此应将其重写为string && string[0],与替代方法相比过于冗长。
  • string.substring(1)比快string.slice(1)

基准测试

  • 此解决方案为4,956,962 ops / s±3.03%,
  • 投票最多的答案为4,577,946个操作/秒±1.2%。
  • 在Google Chrome 57上使用JSBench.me创建。

解决方案的比较


@Green:确实如此,您确定指定的选择器带有两个冒号吗?
Przemek

1
您实际上不想在ES6中将加号(+)用作串联方法。您将要使用模板文字:eslint.org/docs/rules/prefer-template
Sterling Bourne,

42

有一个非常简单的方法可以通过replace实现它。对于ECMAScript 6:

'foo'.replace(/^./, str => str.toUpperCase())

结果:

'Foo'

1
到目前为止的最佳答案,以及显示正则表达式lambda语法的其他要点。我特别喜欢这个,因为它可以在任何地方流畅地剪切和粘贴。
Wade Hatler

使用/^[a-z]/i会比使用更好的.为前一个不会试图取代字母比其他任何字符
代码狂人

38

在CSS中似乎更容易:

<style type="text/css">
    p.capitalize {text-transform:capitalize;}
</style>
<p class="capitalize">This is some text.</p>

这是来自CSS文本转换属性(位于W3Schools)。


28
@Simon并没有说字符串必须作为HTML文档的一部分输出-CSS仅在使用时才有用。
亚当·赫普顿

9
亚当,是的,但是我猜想那里超过95%的Javascript是与HTML和CSS一起使用的。不幸的是,“ capitalize”语句实际上将每个单词都大写,因此您仍然需要JS仅将字符串的第一个字母大写。
西蒙·伊斯特

18
不正确,Dinesh。他说弦的第一个字符
西蒙·东

81
尽管有很多荒谬的答案,但这个答案是错误的,因为它将大写每个单词的第一个字母。@Ryan,如果删除它,您将获得纪律徽章请这样做。
Dan Dascalescu 2012年

10
同意@DanDascalescu-Ryan的回答是完全错误的。
2012年

38
var capitalized = yourstring[0].toUpperCase() + yourstring.substr(1);

37

通常最好先使用CSS处理这类事情,通常,如果您可以使用CSS解决某些问题,请先解决该问题,然后尝试使用JavaScript解决问题,因此在这种情况下,请尝试:first-letter在CSS中使用并应用text-transform:capitalize;

因此,请尝试为此创建一个类,以便可以在全局范围内使用它,例如:.first-letter-uppercase在CSS中添加以下内容:

.first-letter-uppercase:first-letter {
    text-transform:capitalize;
}

另外一个选择是JavaScript,因此最好是这样的:

function capitalizeTxt(txt) {
  return txt.charAt(0).toUpperCase() + txt.slice(1); //or if you want lowercase the rest txt.slice(1).toLowerCase();
}

并这样称呼:

capitalizeTxt('this is a test'); // return 'This is a test'
capitalizeTxt('the Eiffel Tower'); // return 'The Eiffel Tower'
capitalizeTxt('/index.html');  // return '/index.html'
capitalizeTxt('alireza');  // return 'Alireza'

如果您想一遍又一遍地重用它,最好将其附加到javascript原生String,如下所示:

String.prototype.capitalizeTxt = String.prototype.capitalizeTxt || function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
}

并如下调用:

'this is a test'.capitalizeTxt(); // return 'This is a test'
'the Eiffel Tower'.capitalizeTxt(); // return 'The Eiffel Tower'
'/index.html'.capitalizeTxt();  // return '/index.html'
'alireza'.capitalizeTxt();  // return 'Alireza'

36

如果要重新格式化全部大写的文本,则可能需要修改其他示例,例如:

function capitalize (text) {
    return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
}

这将确保更改以下文本:

TEST => Test
This Is A TeST => This is a test

可能值得注意的是,这还将把首字母缩略词转换为小写,因此在大多数情况下可能不是最好的主意
monokrome 16-4-25

另外,GAMITG是否真的进行了编辑,只是从帖子的非代码部分中删除了一块空白?O_O
monokrome

顺便说一句,这会破坏大写字母的首字母缩写,所以请小心y'all <3
monokrome

36

我在现有答案中没有看到与星体平面代码点或国际化有关的任何问题。使用给定脚本,“大写”在每种语言中并不意味着同一件事。

最初,我看不到任何与星体平面代码点相关的问题的答案。有一个,但是有点埋没了(我想是这样的!)


建议的大多数功能如下:

function capitalizeFirstLetter(str) {
  return str[0].toUpperCase() + str.slice(1);
}

但是,某些大小写的字符不在BMP(基本多语言平面,代码点U + 0至U + FFFF)之外。例如,使用以下Deseret文本:

capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉"); // "𐐶𐐲𐑌𐐼𐐲𐑉"

这里的第一个字符不能大写,因为字符串的数组索引属性无法访问“字符”或代码点*。他们访问UTF-16代码单元。切片时也是如此—索引值指向代码单位。

碰巧UTF-16代码单位为1:1,USV代码点在两个范围内(包括U + 0至U + D7FF和U + E000至U + FFFF)。大多数情况下的字符都属于这两个范围,但不是全部。

从ES2015开始,处理此问题变得更加容易。String.prototype[@@iterator]产生对应于代码点**的字符串。因此,例如,我们可以这样做:

function capitalizeFirstLetter([ first, ...rest ]) {
  return [ first.toUpperCase(), ...rest ].join('');
}

capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"

对于更长的字符串,这可能效率不高***-我们真的不需要迭代其余部分。我们可以String.prototype.codePointAt用来获取第一个(可能的)字母,但是我们仍然需要确定切片应从何处开始。避免迭代其余部分的一种方法是测试第一个代码点是否在BMP之外。如果不是,则切片从1开始,如果是,则切片从2开始。

function capitalizeFirstLetter(str) {
  const firstCP = str.codePointAt(0);
  const index = firstCP > 0xFFFF ? 2 : 1;

  return String.fromCodePoint(firstCP).toUpperCase() + str.slice(index);
}

capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"

您可以使用按位数学,而不是在> 0xFFFF那里,但是用这种方式可能更容易理解,并且两者都可以实现相同的目的。

我们还可以在ES5及以下版本中通过在必要时进一步扩展该逻辑来使这项工作生效。ES5中没有用于处理代码点的内在方法,因此我们必须手动测试第一个代码单元是否为代理****:

function capitalizeFirstLetter(str) {
  var firstCodeUnit = str[0];

  if (firstCodeUnit < '\uD800' || firstCodeUnit > '\uDFFF') {
    return str[0].toUpperCase() + str.slice(1);
  }

  return str.slice(0, 2).toUpperCase() + str.slice(2);
}

capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"

在开始时,我还提到了国际化注意事项。其中有些是很难解释,因为他们不仅需要知识是什么正在使用的语言,但也可能需要在语言中的单词的具体知识。例如,爱尔兰语字母“ mb”在单词开头大写为“ mB”。另一个示例,德语eszett,从不以单词开头(afaik),但仍有助于说明问题。小写的eszett(“ß”)大写为“ SS”,但是“ SS”可以小写为“ß”或“ ss”-您需要带德语的带外知识才能知道哪种正确!

这类问题最著名的例子就是土耳其语。在土耳其语拉丁语中,i的大写形式为İ,而I的小写形式为ı,它们是两个不同的字母。幸运的是,我们确实可以解决这个问题:

function capitalizeFirstLetter([ first, ...rest ], locale) {
  return [ first.toLocaleUpperCase(locale), ...rest ].join('');
}

capitalizeFirstLetter("italy", "en") // "Italy"
capitalizeFirstLetter("italya", "tr") // "İtalya"

在浏览器中,用户最喜欢的语言标记由表示navigator.language,在处找到了按优先顺序排列的列表navigator.languages,并且可以(通常)Object(element.closest('[lang]')).lang || YOUR_DEFAULT_HERE在多语言文档中获得给定DOM元素的语言。

在ES2018中引入的在RegExp中支持Unicode属性字符类的代理中,我们可以通过直接表达我们感兴趣的字符来进一步清理内容:

function capitalizeFirstLetter(str, locale=navigator.language) {
  return str.replace(/^\p{CWU}/u, char => char.toLocaleUpperCase(locale));
}

可以进行一些微调,以同样准确地处理字符串中多个单词的大写。该CWUChanges_When_Uppercased字符属性匹配其中,那么,改变大写当所有代码点。我们可以尝试了这一点与titlecased有向图的人物,如荷兰ij例如:

capitalizeFirstLetter('ijsselmeer'); // "IJsselmeer"

在撰写本文时(2020年2月),Firefox / Spidermonkey尚未实现过去两年中引入的任何RegExp功能*****。您可以在Kangax兼容表中查看此功能的当前状态。Babel能够使用对等效模式的属性引用来编译RegExp常量,而无需使用等效模式,但是请注意,生成的代码可能非常庞大。


提出这个问题的人极有可能与Deseret的大写字母或国际化无关。但是,意识到这些问题是一件好事,因为即使目前不关心这些问题,您也很有可能最终会遇到它们。它们不是“边缘”情况,或更确切地说,它们不是边缘定义的情况—在整个国家,大多数人还是会说土耳其语,将代码单元与代码点合并是一个相当常见的错误来源(尤其是与关于表情符号)。字符串和语言都非常复杂!


*从某种意义上说,UTF-16 / UCS2的代码单元也是Unicode代码点,例如从技术上说U + D800是一个代码点,但这并不是它的“含义”……有点……虽然很漂亮模糊。但是,替代品绝对不是USV(Unicode标量值)。

**尽管如果代理代码单元是“孤立的”(即,不是逻辑对的一部分),您仍然可以在这里获得代理。

*** 也许。我还没有测试。除非您确定大写是一个有意义的瓶颈,否则我可能不会大惊小怪-选择您认为最清晰易读的内容。

****这种功能可能希望同时测试第一个和第二个代码单元,而不仅仅是第一个,因为第一个单元可能是孤立的代理。例如,输入“ \ uD800x”将按原样大写X,这可能会或可能不会出现。

***** 如果您想更直接地跟踪进度,这是Bugzilla问题


1
这个答案需要移到最前面。
朗尔·伯格

感谢@RúnarBerg-由于您的评论使我想起了这一点,因此我再次阅读了该书,并意识到我遗漏了最后一个案例和解决方案,值得一提。还试图更好地阐明一些术语。
分号

好答案.....
本·阿斯顿

这个答案很好,我希望我能更多投票。
大卫·巴克

34
function capitalize(s) {
    // returns the first letter capitalized + the string from index 1 and out aka. the rest of the string
    return s[0].toUpperCase() + s.substr(1);
}


// examples
capitalize('this is a test');
=> 'This is a test'

capitalize('the Eiffel Tower');
=> 'The Eiffel Tower'

capitalize('/index.html');
=> '/index.html'

完成@Ram。还包括示例。
Fredrik A.


1
不是@DanDascalescu。我想您可能会争辩说substr/ substring相对于而言slice,在语义上要稍微多一点,但这只是优先考虑的问题。但是,我确实提供了带有问题中提供的字符串的示例,这很不错,'09示例中没有提供。老实说,我认为它可以降低到15岁,我想在StackOverflow上获得业力;)
Fredrik A.

34

这是一个称为ucfirst()的函数 “大写首字母”的缩写):

function ucfirst(str) {
    var firstLetter = str.substr(0, 1);
    return firstLetter.toUpperCase() + str.substr(1);
}

您可以通过调用ucfirst(“ some string”)来大写字符串,例如,

ucfirst("this is a test") --> "This is a test"

它通过将字符串分成两部分来工作。在第一行中,它首先提取firstLetter,然后在第二行中,它通过调用firstLetter.toUpperCase()将大写的字母大写,并将其与字符串的其余部分通过调用str.substr (1)找到)连接起来

您可能会认为这将导致一个空字符串失败,而实际上在像C这样的语言中,您将不得不满足这一要求。但是,在JavaScript中,当您接受一个空字符串的子字符串时,您只会得到一个空字符串。


4
使用String.substring()或String.slice()...不要使用substr()-已过时。
詹姆斯

7
@ 999:它在哪里表明substr()已弃用?三年后的今天,甚至现在还不是,2009年您发表此评论时更不用说了。
Dan Dascalescu 2012年

substr()可能不会被任何流行的ECMAScript实现标记为已弃用(我怀疑它不会很快消失),但这不是ECMAScript规范的一部分。规范的第3版在非规范性附件中对此进行了提及,以“建议使此类属性具有统一的语义,而不必使该属性或其语义成为本标准的一部分”。
Peter Rust 2012年

2
有3种方法做同样的事情(substringsubstrslice)实在是太多了,IMO。我一直使用slice它,因为它支持负索引,它没有令人困惑的arg交换行为,并且它的API与slice其他语言相似。
彼得·鲁斯特

29
String.prototype.capitalize = function(){
    return this.replace( /(^|\s)([a-z])/g , function(m,p1,p2){ return p1+p2.toUpperCase();
    } );
};

用法:

capitalizedString = someString.capitalize();

这是一个文本字符串=>这是一个文本字符串


20
正则表达式对此过于矫kill过正。
安东尼·索特利尔2012年

+1,这是我真正想要的。虽然有一个小错误,但应该是return.this.toLocaleLowerCase().replace(...
tomdemuyt

+1,我发现此页面正在寻找phpfirst的javascript版本的ucfirst,我怀疑这是大多数人找到它的方式。
Benubird13年

@DanDascalescu我发现这很有用,所以+1功利主义和-1保持肛门。他提供了一个示例,因此其功能显而易见。
Travis Webb

String.prototype.capitalize = function(){ return this.replace( /(^|\s)[a-z]/g , function(m){ return m.toUpperCase(); }); }; 我稍微重构一下代码,只需要第一个匹配即可。
IGRACH

28
var str = "test string";
str = str.substring(0,1).toUpperCase() + str.substring(1);

21

签出此解决方案:

var stringVal = 'master';
stringVal.replace(/^./, stringVal[0].toUpperCase()); // returns Master 

3
这应该是公认的答案。主要解决方案不应使用下划线之类的框架。
亚当·麦克阿瑟

3
保存一些击键;)stringVal.replace(/^./, stringVal[0].toUpperCase());
Alfredo Delgado 2015年

1
正则表达式不应在没有必要的地方使用。这是非常低效的,并且也不会使代码更加简洁。而且,stringVal[0]将为undefinedempty stringVal,因此尝试访问属性.toUpperCase()将引发错误。
Przemek

20
yourString.replace(/^[a-z]/, function(m){ return m.toUpperCase() });

(如果您经常使用它,则可以将其封装在一个函数中,甚至可以将其添加到String原型中。)


5
即使获得了相当多的选票,这也是到目前为止发布的最慢的解决方案。我对这篇文章中最受欢迎的答案进行了一些速度测试:forwebonly.com/…–
罗宾·范·巴伦

@RobinvanBaalen您的链接现在已断开。有更新的吗?
布拉德(Brad)

1
正则表达式对此有些矫kill过正,更喜欢简单的方法:str.charAt(0).toUpperCase()+ str.slice(1)
Simon

@Brad不幸的不是
Robin van Baalen

通常,如果您想用正则表达式解决问题,则会遇到两个问题。
Przemek

19

ucfirst如果您这样做,该功能将起作用。

function ucfirst(str) {
    var firstLetter = str.slice(0,1);
    return firstLetter.toUpperCase() + str.substring(1);
}

感谢JP的声明。


2
该函数的好名字!它的名称与PHP等效。实际上,有一个完整的用JS编写的PHP函数库。它称为PHP.js,可以在http://phpjs.org
Hussam

11
一个班轮:string[0].toUpperCase() + string.substring(1)
dimitru博士,2015年

@TarranJones这里是防弹衬里:(string[0] || '').toUpperCase() + string.substring(1)
dimitru博士

@ dr.dimitru:(string[0] || '')您可以只使用惯于惯用的方法string.charAt(0)
Przemek


17
yourString.replace(/\w/, c => c.toUpperCase())

我发现此箭头功能最简单。Replace将匹配\w字符串的第一个字母字符(),并将其转换为大写。不需要任何爱好者。


1
这应该是已被接受的答案,而这几乎是自SO不断授予过时的问题以来的最后一个答案。顺便说一句,最好使用/./两个原因:/\w/跳过所有以前的非字母字符(因此@@ abc将变为@@ Abc),然后不适用于非拉丁字符
CristianTraìna19年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.