Làm cách nào để tạo chữ cái đầu tiên của chữ hoa trong chuỗi JavaScript?


3762

Làm cách nào để tạo chữ cái đầu tiên của chữ hoa, nhưng không thay đổi trường hợp của bất kỳ chữ cái nào khác?

Ví dụ:

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

12
Underscore có một plugin gọi là underscore.opes bao gồm cái này và một loạt các công cụ tuyệt vời khác.
Aaron

những gì về:return str.replace(/(\b\w)/gi,function(m){return m.toUpperCase();});
Muhammad Umer

111
Đơn giản hơn:string[0].toUpperCase() + string.substring(1)
dr.dimitru

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

([initial, ...rest]) => [initial.toUpperCase(), ...rest].join("")
Toàn cảnh

Câu trả lời:


5811

Giải pháp cơ bản là:

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

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

Một số câu trả lời khác sửa đổi String.prototype(câu trả lời này cũng được sử dụng), nhưng tôi sẽ khuyên điều này ngay bây giờ do tính bảo trì (khó tìm ra chức năng đang được thêm vào prototypevà có thể gây xung đột nếu mã khác sử dụng cùng tên / trình duyệt thêm một hàm riêng có cùng tên trong tương lai).

... Và sau đó, có rất nhiều câu hỏi này khi bạn xem xét quốc tế hóa, vì câu trả lời tốt đáng kinh ngạc này (được chôn dưới đây) cho thấy.

Nếu bạn muốn làm việc với các điểm mã Unicode thay vì các đơn vị mã (ví dụ: để xử lý các ký tự Unicode bên ngoài Mặt phẳng đa ngôn ngữ cơ bản), bạn có thể tận dụng thực tế String#[@iterator]hoạt động với các điểm mã và bạn có thể sử dụng toLocaleUpperCaseđể lấy chữ hoa chính xác:

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!)

Đối với các tùy chọn quốc tế hơn nữa, xin vui lòng xem câu trả lời ban đầu dưới đây .


9
chuỗi con được hiểu trong nhiều trình duyệt hơn
lớp nền

6
để thêm vào karim79 - có lẽ nó quá mức cần thiết để biến nó thành một chức năng vì javascript sẽ làm điều tương tự với biến mà không cần gói chức năng. Tôi cho rằng nó sẽ rõ ràng hơn khi sử dụng một hàm, nhưng ngược lại, tại sao nó lại làm phức tạp nó với một hàm bao bọc?
Ross

18
Không phải chúng ta cũng nên tạo ra lát cắt (1) sao?
hasen

177
Không, vì OP đã đưa ra ví dụ này : the Eiffel Tower -> The Eiffel Tower. Thêm vào đó, chức năng được gọi là capitaliseFirstLetterkhông capitaliseFirstLetterAndLowerCaseAllTheOthers.
ban-geengineering

22
Không ai quan tâm đến quy tắc quan trọng của OOP? - Không bao giờ chỉnh sửa các đối tượng bạn không sở hữu? . BTW, lớp lót này trông thanh lịch hơn nhiều:string[0].toUpperCase() + string.substring(1)
dr.dimitru

1350

Đây là một cách tiếp cận hướng đối tượng hơn:

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

Bạn sẽ gọi hàm, như thế này:

"hello world".capitalize();

Với sản lượng dự kiến ​​là:

"Hello world" 

24
Tôi thích giải pháp này vì nó giống như Ruby và Ruby thật ngọt ngào! :) Tôi viết thường tất cả các chữ cái khác của chuỗi để nó hoạt động chính xác như Ruby:return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
ma11hew28

164
Trong thế giới hậu Prototype.js này, không nên thay đổi hoặc mở rộng các đối tượng gốc.
Ryan

191
@rxgx - boogeyman "không mở rộng" hiện đang bắt đầu chết (cảm ơn chúa) và mọi người đang rút đầu ra khỏi jSand và nhận ra đó chỉ là một tính năng ngôn ngữ. Chỉ vì Prototype.js tự mở rộng Đối tượng trong một thời gian ngắn, không có nghĩa là việc mở rộng Người bản địa là xấu. Bạn không nên làm điều đó nếu bạn đang viết mã cho một người tiêu dùng không xác định (như tập lệnh phân tích đi trên các trang web ngẫu nhiên), nhưng điều đó không tốt.
csuwldcat

43
@csuwldcat Điều gì xảy ra nếu một thư viện khác mà bạn đang sử dụng thêm chữ viết hoa mà không biết? Mở rộng các nguyên mẫu là hình thức xấu bất kể Prototype.js có làm điều đó hay không. Với ES6, nội tại sẽ cho phép bạn có bánh của bạn và ăn nó. Tôi nghĩ rằng bạn có thể nhầm lẫn "boogeyman" sắp chết cho những người tạo ra các miếng chêm tuân thủ thông số ECMASCRIPT. Những miếng chêm này hoàn toàn ổn vì một thư viện khác có thêm shim sẽ thực hiện nó theo cùng một cách. Tuy nhiên, nên thêm nội tại không đặc tả của riêng bạn.
Justin Meyer

43
Mở rộng người bản địa là TUYỆT VỜI thực hành xấu. Ngay cả khi bạn nói "oh tôi sẽ không bao giờ sử dụng mã này với bất cứ điều gì khác", bạn (hoặc người khác) có thể sẽ làm được. Sau đó, họ sẽ dành ba ngày để cố gắng tìm ra một số lỗi toán học kỳ lạ vì ai đó đã mở rộng Number.money () để xử lý tiền tệ hơi khác so với thư viện khác của bạn. Nghiêm túc mà nói, tôi đã thấy điều này xảy ra tại một công ty lớn và không đáng để ai đó gỡ lỗi để tìm ra một nhà phát triển thư viện rối tung với các nguyên mẫu bản địa.
phreakhead

574

Trong CSS:

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

80
OP đang yêu cầu một giải pháp JS.
Antonio Max

129
$ ('# mystring_id'). text (chuỗi) .css ('chuyển đổi văn bản', 'viết hoa');
DonMB

21
Ngoài ra, điều này chỉ ảnh hưởng đến việc hiển thị chuỗi - không phải giá trị thực. Nếu nó ở dạng, ví dụ, giá trị vẫn sẽ được gửi như hiện trạng.
dmansfield

12
Câu trả lời này đã giúp tôi nhận ra rằng một giải pháp CSS thực sự phù hợp hơn với những gì tôi đang làm. @dudewad: Câu trả lời có lẽ nên đưa ra từ chối trách nhiệm rằng đây không phải là giải pháp JS nhưng có thể phù hợp hơn tùy theo nhu cầu.
joshden

58
Đối với khoảng 80% người xem đến câu hỏi này, đây sẽ là câu trả lời tốt nhất. Không phải là một câu trả lời cho câu hỏi , nhưng thay vào đó là vấn đề .
Jivan

290

Dưới đây là phiên bản rút gọn của câu trả lời phổ biến nhận được chữ cái đầu tiên bằng cách coi chuỗi là một mảng:

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

Cập nhật:

Theo các bình luận bên dưới, điều này không hoạt động trong IE 7 trở xuống.

Cập nhật 2:

Để tránh undefinedcác chuỗi trống (xem bình luận của @ njzk2 bên dưới ), bạn có thể kiểm tra chuỗi trống:

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

23
Điều này sẽ không hoạt động trong IE <8, vì các trình duyệt đó không hỗ trợ lập chỉ mục chuỗi. Bản thân IE8 hỗ trợ nó, nhưng chỉ cho các chuỗi ký tự - không dành cho các đối tượng chuỗi.
Mathias Bynens

52
ai quan tâm, thị trường IE7 chưa đến 5%! và đó có lẽ là cỗ máy cũ của gremma và grempa của bạn. Tôi nói mã ngắn FTW!
vsync

@MathiasBynens Bạn có biết điều này ảnh hưởng đến bất kỳ trình duyệt không phải IE cũ hơn hay chỉ IE7 không? Nếu không có trình duyệt nào khác bị ảnh hưởng bởi việc lập chỉ mục chuỗi ký tự trong năm 2014, chúng tôi sẽ ổn. :)
hexalys

3
@vsync tôi chỉ có nghĩa là tùy thuộc vào nhân khẩu học dùng của bạn, đôi khi (mặc dù biết ơn ngày càng ít khi chúng ta vượt qua năm 2014 và xa hơn) đó là lợi nhuận để hỗ trợ các trình duyệt cũ như IE7 ...
joshuahedlund

2
@ njzk2 để xử lý một chuỗi trống, bạn có thể cập nhật lên đây: return s && s[0].toUpperCase() + s.slice(1);
joelvh

188

Nếu bạn quan tâm đến hiệu suất của một vài phương pháp khác nhau được đăng:

Dưới đây là các phương pháp nhanh nhất dựa trên bài kiểm tra jsperf này (được sắp xếp từ nhanh nhất đến chậm nhất).

Như bạn có thể thấy, hai phương pháp đầu tiên về cơ bản có thể so sánh về hiệu suất, trong khi đó việc thay đổi String.prototypelà chậm nhất về hiệu suất.

// 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);
}

nhập mô tả hình ảnh ở đây


1
Có vẻ như mã khởi tạo cũng không tạo ra sự khác biệt: jsperf.com/capitalize-first-letter-of-opes/2
user420667 22/03/2016

6
Lưu ý là, thay thế .slice(1)bằng .substr(1)sẽ tăng cường hiệu suất hơn nữa.
Przemek

2
Cân nhắc hợp lý. Mặc dù vậy, trong nhiều trường hợp, hiệu suất đạt được thậm chí không đáng chú ý: Ngay cả cách tiếp cận "chậm nhất" cũng sẽ xử lý chuỗi 19k trong 10 ms. Vì vậy, lấy một trong những thoải mái nhất để sử dụng cho bạn.
Trích dẫn Eddie

1
Trong trường hợp bất kỳ ai cũng tò mò (như tôi), hiệu suất của điều này đã tăng lên như thế nào trong bốn năm qua, ops / giây của chức năng thứ ba trên macbook pro 2018 là 135.307.869, vì vậy nhanh hơn 12,4 lần.
Carlo Field

151

Đối với một trường hợp khác, tôi cần nó để viết hoa chữ cái đầu tiên và viết thường phần còn lại. Các trường hợp sau đây khiến tôi thay đổi chức năng này:

//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
"... Nhưng không thay đổi trường hợp của bất kỳ chữ cái nào khác". Đây không phải là một câu trả lời chính xác cho câu hỏi mà OP đã hỏi.
Carlos Muñoz

2
@ CarlosMuñoz nếu bạn đọc câu mở đầu, ông nói đây là trường hợp khác.
TMH

3
@TomHart Đó chính xác là lý do tại sao nó không phải là một giải pháp cho câu hỏi. Nó phải là một bình luận hoặc một câu hỏi và câu trả lời khác
Carlos Muñoz

15
Tôi đồng ý với bạn về điều đó, nhưng tôi có thể thấy rất nhiều người kết thúc ở đây đang tìm cách làm những gì câu trả lời này làm.
TMH

74

Đây là Giải pháp ECMAScript 6+ 2018 :

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()chậm hơn .substring(), str[0]sẽ undefineddành cho một chuỗi trống và sử dụng các mẫu chữ để tham gia hai phần giới thiệu ở đây 8 ký tự, trong khi +sẽ chỉ giới thiệu 3.
Przemek

4
Quan điểm của câu trả lời của tôi Prz là giới thiệu các tính năng mới được hỗ trợ ES6, cụ thể là các mẫu chữ không được đề cập trong các bài đăng khác. Ý tưởng của StackOverflow là cung cấp cho người tìm kiếm các tùy chọn. Họ có thể lấy khái niệm Văn bản mẫu được mô tả trong câu trả lời này và kết hợp nó với các cải tiến tốc độ vi mô như Chuỗi con v. Slice nếu ứng dụng của họ yêu cầu những mili giây được lưu thêm đó. Câu trả lời của tôi cũng không bao gồm bất kỳ Kiểm tra đơn vị nào, điều này cho thấy rằng bạn không bao giờ nên sao chép trực tiếp câu trả lời StackOverflow. Tôi giả sử nhà phát triển sẽ lấy câu trả lời của tôi và điều chỉnh nó.
Sterling Bourne

Bạn không đạt được gì khi sử dụng các mẫu chữ ở đây và ${}chỉ thêm tiếng ồn. const newStr = str[0].toUpperCase() + str.slice(1);dễ đọc hơn
Boris

1
Đồng ý không đồng ý sau đó về những gì dễ đọc hơn.
Sterling Bourne

67

Nếu bạn đã (hoặc đang cân nhắc) sử dụng lodash, giải pháp rất dễ dàng:

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

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

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

Xem tài liệu của họ: 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 cho chữ hoa đầu tiên:

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

11
Tôi nghĩ rằng ưu tiên nên dành cho vanilla Js vì hầu hết mọi người sẽ không tải xuống toàn bộ khung chỉ để viết hoa một chuỗi.
GGG

7
Trong tất cả các dự án của tôi cho đến nay tôi chưa bao giờ sử dụng lodash. Đừng quên rằng hầu hết mọi người trên google sẽ kết thúc trên trang này và liệt kê một khung làm phương án thay thế là tốt, nhưng không phải là câu trả lời chính.
GGG

2
Vì các câu trả lời khác sử dụng vanilla js, thật tuyệt khi có câu trả lời như thế này, vì rất nhiều người trong chúng ta sử dụng lodash / gạch dưới.
Lu Roman

1
Đây không phải là câu trả lời chính xác vì OP yêu cầu bây giờ thực hiện nó trong Javascript, không phải thư viện Javascript, nhập toàn bộ thư viện làm phụ thuộc vào dự án của bạn. Đừng sử dụng nó.
dudewad

1
Câu hỏi của OP là ở vani ở cuối câu trả lời của tôi.
chovy

62

Viết hoa chữ cái đầu tiên của tất cả các từ trong một chuỗi:

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
Đọc lại câu hỏi: Tôi muốn viết hoa ký tự đầu tiên của chuỗi, nhưng không thay đổi trường hợp của bất kỳ chữ cái nào khác.
JimmyPena

2
Tôi biết tôi làm được. Tôi muốn thêm một điều, trong trường hợp toàn bộ chuỗi bắt đầu viết hoa: Pieces [i] = j + Pieces [i] .substr (1) .toLowerCase ();
Malovich

4
Một giải pháp khác cho trường hợp này: function capitaliseFirstLetters (s) {return s.split ("") .map (function (w) {return w.charAt (0) .toUpperCase () + w.substr (1)}). Tham gia ("")} Có thể là một lớp lót đẹp nếu nó không được đưa vào một chức năng.
Luke Barkings

Sẽ tốt hơn để viết thường toàn bộ chuỗi
Magico

Ngoài chức năng này không trả lời câu hỏi, nó thực sự cũng quá phức tạp. s => s.split(' ').map(x => x[0].toUpperCase() + x.slice(1)).join(' ')
OverCoder

48

Chúng tôi có thể có được nhân vật đầu tiên với một trong những yêu thích của tôi RegExp, trông giống như một nụ cười dễ thương:/^./

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

Và cho tất cả những người nghiện cà phê:

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

... Và cho tất cả những người nghĩ rằng có một cách tốt hơn để làm điều này, mà không cần mở rộng các nguyên mẫu bản địa:

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

2
Có một cách tốt hơn để làm điều này mà không cần sửa đổi nguyên mẫu String.
Big McLUNDHuge

2
@ davidkennedy85 Chắc chắn! Nhưng đây là cách đơn giản, không phải là cách tốt nhất ... ;-)
yckart

Chúa ơi, có một triệu câu trả lời cho câu hỏi này! Giải pháp của bạn trông thậm chí còn đẹp hơn trong es6. 'Answer'.replace(/^./, v => v.toLowerCase())
stwilz


45

Nếu bạn sử dụng underscore.js hoặc Lo-Dash , thư viện underscore.opes cung cấp các phần mở rộng chuỗi, bao gồm viết hoa:

_.capitalize (chuỗi) Chuyển đổi chữ cái đầu tiên của chuỗi thành chữ hoa.

Thí dụ:

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

3
Kể từ phiên bản 3.0.0 , Lo-Dash có sẵn phương thức chuỗi này. Giống như mô tả trong câu trả lời này : _.capitalize("foo") === "Foo".
bardzusny

Ngoài ra còn có hàm underscore.js hữu ích được gọi humanize. Nó chuyển đổi một chuỗi ký tự thiếu, camelized hoặc dasher thành một chuỗi nhân hóa. Đồng thời xóa khoảng trắng bắt đầu và kết thúc và xóa hậu tố '_id'.
Stepan Zakharov

1
Từ phiên bản 4 *, Lodash cũng viết thường () mọi chữ cái khác, hãy cẩn thận!
Igor Loskutov

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
}

Và sau đó:

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

Cập nhật tháng 11/2016 (ES6), chỉ dành cho FUN:

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

sau đó capitalize("hello") // Hello


3
Tôi nghĩ rằng đây là một giải pháp kém vì 2 lý do: Sửa đổi nguyên mẫu của nguyên thủy là một ý tưởng tồi. Nếu thông số kỹ thuật thay đổi và họ quyết định chọn 'viết hoa' làm tên thuộc tính proto mới, bạn đang phá vỡ chức năng ngôn ngữ cốt lõi. Ngoài ra, tên phương thức được chọn là kém. Thoạt nhìn, tôi nghĩ điều này sẽ tận dụng toàn bộ chuỗi. Sử dụng một tên mô tả hơn như ucFirst của PHP hoặc một cái gì đó tương tự có thể là một ý tưởng tốt hơn.
dudewad

Câu trả lời ES6 khác đơn giản hơn : const capitalize = ([first,...rest]) => first.toUpperCase() + rest.join('').toLowerCase();.
Dan Dascalescu

44

Ngắn nhất 3 giải pháp, 1 và 2 trường hợp xử lý khi schuỗi là "", nullundefined:

 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

Chỉ CSS

p::first-letter {
  text-transform: uppercase;
}
  • Mặc dù được gọi ::first-letter, nó áp dụng cho ký tự đầu tiên , tức là trong trường hợp chuỗi %a, bộ chọn này sẽ áp dụng %và như vậy asẽ không được viết hoa.
  • Trong IE9 + hoặc IE5.5 +, nó được hỗ trợ trong ký hiệu kế thừa chỉ với một dấu hai chấm ( :first-letter).

ES2015 một lớp lót

Vì có rất nhiều câu trả lời, nhưng không có câu trả lời nào trong ES2015 có thể giải quyết vấn đề ban đầu một cách hiệu quả, tôi đã đưa ra những điều sau:

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

Nhận xét

  • parameters => functionđược gọi là chức năng mũi tên .
  • Tôi đã đi với tên capitalizeFirstCharthay vì capitalizeFirstLetter, vì OP đã không yêu cầu mã viết hoa chữ cái đầu tiên trong toàn bộ chuỗi, nhưng ký tự đầu tiên (tất nhiên nếu đó là chữ cái).
  • constcung cấp cho chúng tôi khả năng khai báo capitalizeFirstCharlà hằng số, điều này mong muốn vì là một lập trình viên, bạn nên luôn luôn nói rõ ý định của mình.
  • Trong điểm chuẩn tôi thực hiện không có sự khác biệt đáng kể giữa string.charAt(0)string[0]. Tuy nhiên, lưu ý rằng đó string[0]sẽ là undefinedchuỗi rỗng, do đó, nó nên được viết lại string && string[0], đó là quá dài dòng, so với thay thế.
  • string.substring(1)nhanh hơn string.slice(1).

Điểm chuẩn

  • 4.956.962 ops / s ± 3.03% cho giải pháp này,
  • 4.577.946 ops / s ± 1,2% cho câu trả lời được bình chọn nhiều nhất.
  • Được tạo bằng JSBench.me trên Google Chrome 57.

So sánh giải pháp


@Green: đúng vậy , bạn có chắc bạn đã chỉ định bộ chọn với hai dấu hai chấm không?
Przemek

1
Bạn thực sự không muốn sử dụng dấu cộng (+) làm phương pháp nối trong ES6. Bạn sẽ muốn sử dụng mẫu chữ: eslint.org/docs/rules/prefer-template
Sterling Bourne

42

Có một cách rất đơn giản để thực hiện nó bằng cách thay thế . Đối với ECMAScript 6:

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

Kết quả:

'Foo'

1
Câu trả lời tốt nhất cho đến nay, và thêm điểm để hiển thị cú pháp regex lambda. Tôi đặc biệt thích cái này vì nó có thể là một phần cắt và dán trôi chảy ở bất cứ đâu.
Wade Hatler

Sử dụng /^[a-z]/isẽ tốt hơn sử dụng .như cách trước sẽ không thay thế bất kỳ ký tự nào ngoài bảng chữ cái
Code Maniac

38

Nó có vẻ dễ dàng hơn trong CSS:

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

Đây là từ Thuộc tính chuyển đổi văn bản CSS (tại W3Schools ).


29
@Simon Không nói rõ rằng chuỗi này nhất thiết phải là đầu ra như một phần của tài liệu HTML - CSS sẽ chỉ được sử dụng nếu có.
Adam Hepton

9
Adam, đúng, nhưng tôi đoán rằng hơn 95% Javascript ngoài kia được sử dụng với HTML & CSS. Thật không may, câu lệnh "viết hoa" thực sự viết hoa từng chữ , vì vậy bạn vẫn cần JS chỉ viết hoa chữ cái đầu tiên của chuỗi.
Simon East

18
Không chính xác, Dinesh. Ông nói nhân vật đầu tiên của chuỗi .
Simon East

81
Câu trả lời này, mặc dù có một số lượng upvote vô lý, chỉ là sai, vì nó sẽ viết hoa chữ cái đầu tiên của mỗi từ. @Ryan, bạn sẽ kiếm được một huy hiệu Kỷ luật nếu bạn xóa nó. Xin hãy làm như vậy.
Dan Dascalescu

10
Đồng ý với @DanDascalescu - Câu trả lời của Ryan là hoàn toàn sai.
Timo

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

38

Tôi đã không thấy bất kỳ đề cập nào trong các câu trả lời hiện có về các vấn đề liên quan đến các điểm mã máy bay hoặc quốc tế hóa. Cấm Uppercase không có nghĩa là điều tương tự trong mọi ngôn ngữ sử dụng một tập lệnh nhất định.

Ban đầu tôi không thấy bất kỳ câu trả lời nào giải quyết các vấn đề liên quan đến các điểm mã máy bay. Có một cái , nhưng nó hơi bị chôn vùi (như cái này sẽ thế, tôi đoán vậy!)


Hầu hết các chức năng được đề xuất trông như thế này:

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

Tuy nhiên, một số ký tự được đặt bên ngoài BMP (mặt phẳng đa ngôn ngữ cơ bản, mã điểm U + 0 đến U + FFFF). Ví dụ: lấy văn bản Deseret này:

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

Ký tự đầu tiên ở đây không viết hoa được vì các thuộc tính được lập chỉ mục theo chuỗi của các chuỗi không truy cập vào các ký tự của Wikipedia hoặc các điểm mã *. Họ truy cập các đơn vị mã UTF-16. Điều này cũng đúng khi cắt - giá trị chỉ mục trỏ vào các đơn vị mã.

Điều xảy ra là các đơn vị mã UTF-16 là 1: 1 với các điểm mã USV trong hai phạm vi, bao gồm U + 0 đến U + D7FF và U + E000 đến U + FFFF. Hầu hết các nhân vật vỏ bọc rơi vào hai phạm vi đó, nhưng không phải tất cả.

Từ ES2015 trở đi, việc giải quyết việc này trở nên dễ dàng hơn một chút. String.prototype[@@iterator]mang lại chuỗi tương ứng với các điểm mã **. Vì vậy, ví dụ, chúng ta có thể làm điều này:

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

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

Đối với các chuỗi dài hơn, điều này có thể không hiệu quả khủng khiếp *** - chúng tôi thực sự không cần phải lặp lại phần còn lại. Chúng ta có thể sử dụng String.prototype.codePointAtđể nhận được chữ cái đầu tiên (có thể), nhưng chúng ta vẫn cần xác định nơi lát cắt sẽ bắt đầu. Một cách để tránh lặp lại phần còn lại sẽ là kiểm tra xem điểm mã đầu tiên có nằm ngoài BMP hay không; nếu không, lát cắt bắt đầu từ 1 và nếu có, lát cắt bắt đầu từ 2.

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

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

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

Bạn có thể sử dụng toán bitwise thay vì > 0xFFFFở đó, nhưng có lẽ dễ hiểu hơn theo cách này và sẽ đạt được điều tương tự.

Chúng tôi cũng có thể làm cho công việc này hoạt động trong ES5 trở xuống bằng cách đưa logic đó đi xa hơn một chút nếu cần thiết. Không có phương thức nội tại nào trong ES5 để làm việc với các điểm mã, vì vậy chúng tôi phải kiểm tra thủ công xem đơn vị mã đầu tiên có phải là đại diện thay thế ****:

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("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"

Lúc đầu tôi cũng đề cập đến những cân nhắc quốc tế hóa. Một số trong số này là rất khó khăn để chiếm bởi vì họ đòi hỏi kiến thức không chỉ của những gì ngôn ngữ đang được sử dụng, nhưng cũng có thể đòi hỏi kiến thức cụ thể của các từ trong ngôn ngữ. Ví dụ, chữ "mb" của Ailen viết hoa là "mB" khi bắt đầu một từ. Một ví dụ khác, eszett của Đức, không bao giờ bắt đầu một từ (afaik), nhưng vẫn giúp minh họa vấn đề. Chữ eszett chữ thường (chữ nhật ký) viết hoa thành chữ viết hoa, chữ viết tắt chữ viết hoa có thể viết hoa thành chữ viết hoa hoặc chữ viết tắt - bạn có thể hiểu biết về ngôn ngữ tiếng Đức để biết điều đó là chính xác!

Ví dụ nổi tiếng nhất về các loại vấn đề này, có lẽ, là tiếng Thổ Nhĩ Kỳ. Trong tiếng Latin tiếng Thổ Nhĩ Kỳ, dạng viết hoa của chữ i là chữ I, trong khi dạng chữ thường của chữ I là - chúng là hai chữ cái khác nhau. May mắn thay, chúng tôi có một cách để giải thích cho điều này:

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

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

Trong trình duyệt, thẻ ngôn ngữ ưa thích nhất của người dùng được chỉ định bởi navigator.language, một danh sách theo thứ tự ưu tiên được tìm thấy tại navigator.languagesvà ngôn ngữ của một thành phần DOM nhất định có thể được lấy (thường) bằng các Object(element.closest('[lang]')).lang || YOUR_DEFAULT_HEREtài liệu đa ngôn ngữ.

Trong các tác nhân hỗ trợ các lớp ký tự thuộc tính Unicode trong RegExp, được giới thiệu trong ES2018, chúng ta có thể dọn dẹp thêm mọi thứ bằng cách thể hiện trực tiếp những ký tự mà chúng ta quan tâm:

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

Điều này có thể được điều chỉnh một chút để xử lý viết hoa nhiều từ trong một chuỗi với độ chính xác khá tốt. Thuộc tính CWUhoặc thay đổi_When_Uppercued phù hợp với tất cả các điểm mã, tốt, thay đổi khi cấp trên. Chúng ta có thể thử điều này với một nhân vật digraph titlecased như người Hà Lan ij ví dụ:

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

Tại thời điểm viết bài (tháng 2 năm 2020), Firefox / Spidermonkey vẫn chưa triển khai bất kỳ tính năng RegExp nào được giới thiệu trong hai năm qua *****. Bạn có thể kiểm tra trạng thái hiện tại của tính năng này tại bảng compat Kangax . Babel có thể biên dịch các chữ RegExp với các tham chiếu thuộc tính đến các mẫu tương đương mà không có chúng, nhưng lưu ý rằng mã kết quả có thể rất lớn.


Trong tất cả khả năng, những người hỏi câu hỏi này sẽ không quan tâm đến việc viết hoa hoặc quốc tế hóa Deseret. Nhưng thật tốt khi nhận thức được những vấn đề này bởi vì rất có thể bạn sẽ gặp phải chúng ngay cả khi chúng không phải là mối quan tâm hiện tại. Chúng không phải là các trường hợp cạnh edge, hay đúng hơn, chúng không phải là các trường hợp cạnh theo định nghĩa - có cả một quốc gia nơi hầu hết mọi người nói tiếng Thổ Nhĩ Kỳ, và các đơn vị mã kết hợp với mật mã là một nguồn lỗi khá phổ biến (đặc biệt là với liên quan đến biểu tượng cảm xúc). Cả chuỗi và ngôn ngữ đều khá phức tạp!


* Đơn vị mã của UTF-16 / UCS2 cũng là các điểm mã Unicode theo nghĩa, ví dụ, U + D800 về mặt kỹ thuật là một điểm mã, nhưng đó không phải là ý nghĩa của nó ở đây ... mặc dù ... nó khá hay mờ. Tuy nhiên, những gì người thay thế chắc chắn không phải là USVs (giá trị vô hướng Unicode).

** Mặc dù nếu một đơn vị mã thay thế là mồ côi mồ côi - tức là không phải là một phần của cặp logic - bạn vẫn có thể nhận được người thay thế ở đây.

*** có lẽ. Tôi đã không kiểm tra nó. Trừ khi bạn xác định viết hoa là một nút cổ chai có ý nghĩa, tôi có thể sẽ không đổ mồ hôi - hãy chọn bất cứ điều gì bạn tin là rõ ràng và dễ đọc nhất.

**** một chức năng như vậy có thể muốn kiểm tra cả đơn vị mã thứ nhất và thứ hai thay vì chỉ đơn vị thứ nhất, vì có thể đơn vị đầu tiên là một đại diện thay thế mồ côi. Ví dụ: đầu vào "\ uD800x" sẽ viết hoa chữ X như vốn có, có thể hoặc không được mong đợi.

***** Đây là vấn đề Bugzilla nếu bạn muốn theo dõi tiến trình trực tiếp hơn.


2
Câu trả lời này cần phải được chuyển đến phía trước.
Rúnar Berg

Cảm ơn @ RúnarBerg - vì nhận xét của bạn đã nhắc nhở tôi về điều này, tôi đọc lại nó và nhận ra rằng tôi đã bỏ qua một trường hợp cuối cùng và giải pháp đáng nói. Cũng đã cố gắng để làm rõ một số thuật ngữ tốt hơn.
Dấu chấm phẩy

Câu trả lời tuyệt vời .....
Ben Aston

Câu trả lời này là tuyệt vời, tôi ước tôi có thể nâng cao nó nhiều hơn nữa.
David Barker

37

Nói chung, tốt hơn hết là xử lý các loại công cụ này bằng CSS , nói chung, nếu bạn có thể giải quyết vấn đề gì đó bằng CSS, trước tiên hãy thử JavaScript để giải quyết vấn đề của bạn, vì vậy trong trường hợp này hãy thử sử dụng :first-letterCSS và áp dụngtext-transform:capitalize;

Vì vậy, hãy thử tạo một lớp cho điều đó, để bạn có thể sử dụng nó trên toàn cầu, ví dụ: .first-letter-uppercasevà thêm một cái gì đó như dưới đây vào CSS của bạn:

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

Ngoài ra, tùy chọn thay thế là JavaScript, vì vậy tốt nhất sẽ là một cái gì đó như thế này:

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

và gọi nó như:

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'

Nếu bạn muốn sử dụng lại nhiều lần, tốt hơn hết là đính kèm nó vào Chuỗi gốc javascript, vì vậy một cái gì đó như dưới đây:

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

và gọi nó như dưới đây:

'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

Nếu bạn muốn định dạng lại văn bản toàn chữ hoa, bạn có thể muốn sửa đổi các ví dụ khác như sau:

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

Điều này sẽ đảm bảo rằng văn bản sau được thay đổi:

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

Có lẽ đáng chú ý rằng điều này cũng sẽ chuyển đổi những thứ như từ viết tắt thành chữ thường, vì vậy có lẽ không phải là ý tưởng tốt nhất trong hầu hết các trường hợp
đơn sắc

Ngoài ra, GAMITG có thực sự chỉnh sửa chỉ để xóa một phần khoảng trắng khỏi phần không phải là mã của bài đăng không? O_O
đơn sắc

btw, điều này sẽ phá vỡ các từ viết tắt, vì vậy hãy cẩn thận <3
monokrom 15/03/19

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'

Xong @Ram. Cũng bao gồm các ví dụ.
Fredrik A.

Làm thế nào là tốt hơn so với câu trả lời năm 2009 ?
Dan Dascalescu

1
Đó không phải là @DanDascalescu. Tôi cho rằng bạn có thể lập luận rằng substr/ substringlà một chút ngữ nghĩa trái ngược với slice, nhưng đó chỉ là vấn đề ưu tiên. Tuy nhiên, tôi đã bao gồm các ví dụ với các chuỗi được cung cấp trong câu hỏi, đây là một điểm tuyệt vời không có trong ví dụ '09. Tôi thành thật nghĩ rằng nó sôi sục đến 15 tuổi khi tôi muốn nghiệp chướng trên StackOverflow;)
Fredrik A.

34

Đây là một hàm gọi là ucfirst () (viết tắt của "chữ in hoa đầu tiên"):

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

Bạn có thể viết hoa một chuỗi bằng cách gọi ucfirst ("một số chuỗi") - ví dụ:

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

Nó hoạt động bằng cách chia chuỗi thành hai mảnh. Trên dòng đầu tiên, nó kéo ra FirstLetter và sau đó trên dòng thứ hai, nó viết hoa FirstLetter bằng cách gọi FirstLetter.toUpperCase () và nối nó với phần còn lại của chuỗi, được tìm thấy bằng cách gọi str.substr (1) .

Bạn có thể nghĩ rằng điều này sẽ thất bại đối với một chuỗi trống và thực sự trong một ngôn ngữ như C, bạn sẽ phải phục vụ cho điều này. Tuy nhiên, trong JavaScript, khi bạn lấy một chuỗi con của một chuỗi rỗng, bạn chỉ cần lấy lại một chuỗi trống.


4
Sử dụng String.subopes () hoặc String.slice () ... Đừng sử dụng chất nền () - nó không được dùng nữa.
James

7
@ 999: Nơi nào nói rằng substr()không được chấp nhận? Thậm chí không phải bây giờ, ba năm sau, hãy để một mình trở lại vào năm 2009 khi bạn đưa ra nhận xét này.
Dan Dascalescu

substr()có thể không được đánh dấu là không được chấp nhận bởi bất kỳ triển khai ECMAScript phổ biến nào (tôi nghi ngờ rằng nó sẽ không biến mất bất cứ lúc nào sớm), nhưng nó không phải là một phần của thông số ECMAScript. Phiên bản thứ 3 của thông số kỹ thuật đề cập đến nó trong phụ lục không quy phạm để "gợi ý ngữ nghĩa thống nhất cho các thuộc tính đó mà không làm cho các thuộc tính hoặc ngữ nghĩa của chúng trở thành một phần của tiêu chuẩn này".
Peter Rust

2
Có 3 phương pháp mà làm điều tương tự ( substring, substrslice) là quá nhiều, IMO. Tôi luôn sử dụng slicevì nó hỗ trợ các chỉ mục tiêu cực, nó không có hành vi hoán đổi gây nhầm lẫn và API của nó tương tự như slicetrong các ngôn ngữ khác.
Peter Rust

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

Sử dụng:

capitalizedString = someString.capitalize();

Đây là một chuỗi văn bản => Đây là một chuỗi văn bản


20
Biểu thức thông thường là quá mức cho việc này.
Anthony Sottile

+1, đây là những gì tôi đã thực sự tìm kiếm. Tuy nhiên, có một lỗi nhỏ, nó phải là return.this.toLocaleLowerCase().replace(...
tomdemuyt

+1, tôi thấy trang này đang tìm kiếm một phiên bản javascript của phps ucfirst, điều mà tôi nghi ngờ là cách mà hầu hết mọi người tìm thấy nó.
Benubird

@DanDascalescu Tôi thấy điều này hữu ích, nên +1 chủ nghĩa thực dụng và -1 khả năng giữ lại hậu môn. Ông bao gồm một ví dụ, vì vậy chức năng của nó là rõ ràng.
Travis Webb

String.prototype.capitalize = function(){ return this.replace( /(^|\s)[a-z]/g , function(m){ return m.toUpperCase(); }); }; Tôi cấu trúc lại mã của bạn một chút, bạn chỉ cần một trận đấu đầu tiên.
IGRACH

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

21

Kiểm tra giải pháp này:

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

3
Đây phải là câu trả lời được chấp nhận. Giải pháp chính không nên sử dụng một khung như gạch dưới.
Adam McArthur

3
Lưu một số tổ hợp phím;)stringVal.replace(/^./, stringVal[0].toUpperCase());
Alfredo Delgado

1
Regex không nên được sử dụng khi không cần thiết. Nó rất kém hiệu quả và nó cũng không tạo ra mã nào ngắn gọn nữa. Hơn nữa, stringVal[0]sẽ là undefinedtrống rỗng stringVal, và như vậy nỗ lực truy cập tài sản .toUpperCase()sẽ gây ra lỗi.
Przemek

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

(Bạn có thể gói nó trong một hàm hoặc thậm chí thêm nó vào nguyên mẫu Chuỗi nếu bạn sử dụng nó thường xuyên.)


5
Mặc dù điều này có khá nhiều phiếu bầu, đây là giải pháp chậm nhất được đăng ở đây. Tôi đã kết hợp một chút speedtest với các câu trả lời phổ biến nhất từ ​​bài đăng này, tại đây: forwebonly.com/ Khăn
Robin van Baalen

@RobinvanBaalen Liên kết của bạn hiện bị hỏng. Có một bản cập nhật?
Brad

1
Regapi là quá mức cần thiết cho điều này, thích đơn giản hơn: str.charAt (0) .toUpperCase () + str.slice (1)
Simon

@Brad tiếc là không
Robin van Baalen

Thông thường, nếu bạn muốn giải quyết vấn đề của mình bằng regex, bạn sẽ gặp hai vấn đề.
Przemek

19

Các ucfirstchức năng hoạt động nếu bạn làm điều đó như thế này.

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

Cảm ơn JP đã tuyên bố.


2
tên đẹp cho chức năng! Tên của nó giống hệt với PHP. Thực sự có toàn bộ thư viện các hàm PHP được viết bằng JS; nó được gọi là PHP.js và được tìm thấy trên http://phpjs.org
Hussam

11
Một lớp lót:string[0].toUpperCase() + string.substring(1)
dr.dimitru

@TarranJones ở đây có khả năng chống đạn:(string[0] || '').toUpperCase() + string.substring(1)
dr.dimitru

@ dr.dimitru: Thay vì thành ngữ (string[0] || '')bạn chỉ có thể string.charAt(0).
Przemek


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

Tôi tìm thấy chức năng mũi tên này dễ nhất. Thay thế khớp với ký tự chữ cái đầu tiên ( \w) của chuỗi của bạn và chuyển đổi nó thành chữ hoa. Không có gì fancier cần thiết.


1
Đây phải là câu trả lời được chấp nhận, thay vào đó là câu trả lời gần như cuối cùng vì SO liên tục trao giải cho những câu hỏi lỗi thời. Btw, tốt hơn là sử dụng /./vì hai lý do: /\w/sẽ bỏ qua tất cả các ký tự không phải chữ cái trước đó (vì vậy @@ abc sẽ trở thành @@ Abc), và sau đó nó không hoạt động với các ký tự không phải là tiếng Latin
Cristian Traìna
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.