Chuyển đổi chuỗi thành trường hợp tiêu đề với JavaScript


549

Có một cách đơn giản để chuyển đổi một chuỗi thành trường hợp tiêu đề? Ví dụ john smithtrở thành John Smith. Tôi không tìm kiếm thứ gì đó phức tạp như giải pháp của John Resig , chỉ (hy vọng) một loại nào đó một hoặc hai lớp lót.


Có nhiều phương pháp khác nhau, chúng ta có một số thống kê hiệu suất?
theAnubhav

Vui lòng chọn câu trả lời ngắn này stackoverflow.com/a/57689168/10373693 Tôi hy vọng đó sẽ là câu trả lời mà bạn đang tìm kiếm.
Abhishek Kumar

Câu trả lời:


740

Thử cái này:

    function toTitleCase(str) {
        return str.replace(
            /\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>


14
Bất cứ ai có thể giải thích, tại sao \w\S*được sử dụng, thay vì \w+hoặc \w*ví dụ? Tôi không biết, tại sao bạn muốn bao gồm bất cứ thứ gì ngoài không gian và do đó đổi Jim-Bob thành Jim-bob .
martinczerwi

5
@martinCzerwi \w\S*cũng gây ra Jim-bobvấn đề về phía chúng tôi. Sử dụng \w*giải quyết điều này.
Bouke

14
/([^\W_]+[^\s-]*) */ggiải quyết Jim-Bobvấn đề, tức là:jim-bob --> Jim-Bob
đệ quy.ninja

15
Nếu đó jim-bob --> Jim-Boblà mong muốn của bạn, có lẽ bạn nên làm /\b\w+/g. Ví dụ:str.replace(/\b\w+/g,function(s){return s.charAt(0).toUpperCase() + s.substr(1).toLowerCase();});
vol7ron

3
\w\S*được sử dụng thay vì \w+hoặc \w*để các từ như Don'tkhông được sửa đổi Don'T, nhưng như những từ khác đã chỉ ra \w\S*nguyên nhân gây ra các từ có gạch nối.
doubleDown

198

Một cách thanh lịch hơn một chút, điều chỉnh chức năng của Greg Dean:

String.prototype.toProperCase = function () {
    return this.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
};

Gọi nó như:

"pascal".toProperCase();

3
Hãy ghi nhớ nếu bạn có một người dùng có dấu gạch ngang trong tên của họ và họ nhập Jo-Ann Smith, mã này sẽ chuyển đổi chúng thành Jo-ann Smith(lưu ý chữ thường atrong Ann).
dbau

18
@daniellmb Tại sao anh ta không nên thay đổi nguyên mẫu String? Tôi nghĩ đó là một giải pháp tốt. Hãy nghĩ về các lớp mở ruby, việc thêm các hàm vào các lớp hiện có là hoàn toàn hợp lệ và nó được chấp nhận rộng rãi.
marco-fiset

97
@ marco-fiset Vì nó không chơi tốt với người khác! Điều tồi tệ xảy ra khi bạn có 2 thư viện đang cố gắng sửa đổi các đối tượng JavaScript gốc với các thay đổi không tương thích. Hãy tưởng tượng nếu jQuery và Google Maps tuân theo mẫu thiết kế này, bạn không thể có cả hai trên cùng một trang.
daniellmb

5
@daniellmb Một điểm tuyệt vời. Tiền tố tên phương thức sẽ giúp tránh điều này, vì sẽ làm cho phương thức không thể đếm được.
mikemaccana

60
Tôi cảm thấy như câu lệnh "không sửa đổi các đối tượng JavaScript gốc" giống như "không bao giờ sử dụng goto" hoặc "eval is evil". Có rất nhiều trường hợp nó là ok. Nếu bạn có toàn quyền kiểm soát dự án của mình và tất nhiên không có kế hoạch phát hành nó dưới dạng thư viện, tôi thấy không có vấn đề gì với phương pháp này.
FoxMulder900

175

Cố gắng áp dụng kiểu CSS biến đổi văn bản cho các điều khiển của bạn.

ví dụ: (text-transform: capitalize);

Chỉ sử dụng một cách tiếp cận JS khi thực sự cần thiết.


36
-1. Css này hoạt động, nhưng không hoạt động như hầu hết mọi người mong đợi bởi vì nếu văn bản bắt đầu như tất cả các chữ hoa thì không có hiệu lực. webmasterworld.com/forum83/7506.htm
whitneyland

2
@Akshar: Quy tắc viết thường sẽ được thay thế bằng quy tắc trường hợp tiêu đề. Vì css không sửa đổi nội dung nguồn, nên hiệu quả là quy tắc chữ thường được loại bỏ (để lại nội dung nguồn trong tất cả các chữ hoa) và sau đó quy tắc Titlecase sẽ được áp dụng (không làm gì cả).
dokkaebi

42
JS được sử dụng bên ngoài các trình duyệt.
mikemaccana

4
Câu hỏi là: "Có cách nào đơn giản để chuyển đổi một chuỗi thành trường hợp tiêu đề không?" . Câu trả lời này không chuyển đổi một chuỗi. Đây là một phong cách được áp dụng trên đỉnh một chuỗi.
kingPuppy

Nếu bạn muốn dữ liệu trong cơ sở dữ liệu của mình sạch sẽ, để dữ liệu có thể được sử dụng sạch khi chuyển sang dịch vụ của bên thứ 3 hoặc xuất sang CSV, thì CSS không thực sự là một tùy chọn. CSS dành cho mỹ phẩm, và trong khi nó đã phát triển rất nhiều trong những năm qua và bạn có thể sử dụng nó để giải quyết các loại vấn đề này, giải pháp vẫn là mỹ phẩm và nó không giải quyết được vấn đề tiềm ẩn.
Adam Reis

118

Đây là phiên bản của tôi, IMO thật dễ hiểu và thanh lịch.

var str = "foo bar baz"

console.log(

str.split(' ')
   .map(w => w[0].toUpperCase() + w.substr(1).toLowerCase())
   .join(' ')

)
// returns "Foo Bar Baz"


3
Ngoài ra, bạn có thể viết thường chuỗi con trong ánh xạ:str.split(' ').map(i => i[0].toUpperCase() + i.substring(1).toLowerCase()).join(' ')
Dave Land

5
Tôi không đồng ý với cuộc gọi .toLowerCase(). Các tên như "McDonald" hoặc các từ viết tắt như "ASAP" sẽ giữ lại các ký tự viết hoa của chúng. Nếu ai đó thực sự chuyển qua một chuỗi như "heLLO", ứng dụng không nên cho rằng các chữ cái viết hoa là không chính xác.
Thomas Higginbotham

1
@ThomasHigginbotham Thế này thì sao? String.prototype.toTitleCase = function (blnForceLower) { var strReturn; (blnForceLower ? strReturn = this.toLowerCase() : strReturn = this); return strReturn .split(' ') .map(i => i[0].toUpperCase() + i.substr(1)) .join(' '); }
Sean Kendle

Có, cung cấp một tùy chọn để buộc chữ thường sẽ được ưu tiên.
Thomas Higginbotham

1
Điều này sẽ phá vỡ nếu strlà một nhân vật duy nhất.
Madbreaks

103

Đây là chức năng của tôi chuyển đổi sang trường hợp tiêu đề nhưng cũng giữ các từ viết tắt được xác định là chữ hoa và các từ nhỏ là chữ thường:

String.prototype.toTitleCase = function() {
  var i, j, str, lowers, uppers;
  str = this.replace(/([^\W_]+[^\s-]*) */g, function(txt) {
    return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
  });

  // Certain minor words should be left lowercase unless 
  // they are the first or last words in the string
  lowers = ['A', 'An', 'The', 'And', 'But', 'Or', 'For', 'Nor', 'As', 'At', 
  'By', 'For', 'From', 'In', 'Into', 'Near', 'Of', 'On', 'Onto', 'To', 'With'];
  for (i = 0, j = lowers.length; i < j; i++)
    str = str.replace(new RegExp('\\s' + lowers[i] + '\\s', 'g'), 
      function(txt) {
        return txt.toLowerCase();
      });

  // Certain words such as initialisms or acronyms should be left uppercase
  uppers = ['Id', 'Tv'];
  for (i = 0, j = uppers.length; i < j; i++)
    str = str.replace(new RegExp('\\b' + uppers[i] + '\\b', 'g'), 
      uppers[i].toUpperCase());

  return str;
}

Ví dụ:

"TO LOGIN TO THIS SITE and watch tv, please enter a valid id:".toTitleCase();
// Returns: "To Login to This Site and Watch TV, Please Enter a Valid ID:"

1
Tôi thích bạn, tôi cũng gặp phải vấn đề khi xử lý các số La Mã ... chỉ cần vá nó với I, II, III, IV, v.v.
Marcelo

2
Đã sửa. Regex trong dòng thứ ba đã được thay đổi từ /\w\S*/gđể /([^\W_]+[^\s-]*) */gmỗi bình luận @ awashburn của trên đến địa chỉ này.
Gian hàng Geoffrey

2
Có một lợi thế để đạt được bằng cách sử dụng mô hình regex của bạn hơn /\b\w+/g, mà tôi thấy là dễ hiểu hơn?
Michael - Clay Shirky ở đâu

2
Không phải là tôi có thể thấy, tôi chỉ đơn giản là lấy một đề nghị của người bình luận khác để giải quyết vấn đề từ có gạch nối; nhưng regex của bạn dường như cũng làm như vậy, và sự đơn giản luôn tốt hơn. Cho hậu thế và tương lai du khách đến bài này, tôi chỉ cần thay đổi regex trong dòng thứ ba từ /([^\W_]+[^\s-]*) */gđể /\b\w+/gmỗi @ bình luận của Michael; xin vui lòng bình luận nếu bạn tìm thấy một trường hợp mà regex phức tạp hơn là cần thiết.
Gian hàng Geoffrey

1
Tôi đã thay đổi regex dòng thứ 3 thành /\b[\w-\']+/gđể cho phép các từ có dấu gạch ngang và dấu nháy đơn trong các từ.
Shamocation Bhattacharya

47

Tôi thích sau đây hơn các câu trả lời khác. Nó chỉ khớp với chữ cái đầu tiên của mỗi từ và viết hoa nó. Mã đơn giản hơn, dễ đọc hơn và ít byte hơn. Nó bảo tồn các chữ in hoa hiện có để ngăn chặn các từ viết tắt. Tuy nhiên, bạn luôn có thể gọi toLowerCase()trên chuỗi của bạn đầu tiên.

function title(str) {
  return str.replace(/(^|\s)\S/g, function(t) { return t.toUpperCase() });
}

Bạn có thể thêm phần này vào nguyên mẫu chuỗi của bạn, điều này sẽ cho phép bạn 'my string'.toTitle()như sau:

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

Thí dụ:


3
Nó thậm chí còn đẹp hơn như một lambdaconst titleCase = (str) => str.replace(/\b\S/g, t => t.toUpperCase());
0xcaff

Tôi không muốn phá IE, nhưng ừ nếu ứng dụng không nhạy cảm với trình duyệt thì nó có thể ngắn hơn.
Tom Kay

Đây chỉ là một giải pháp một phần - op yêu cầu làm thế nào để chuyển đổi một chuỗi thành trường hợp tiêu đề. Câu trả lời này không thực hiện được điều đó cho đầu vào như thế nào NoT qUiITe.
Madbreaks

@Madbreaks Câu hỏi không quy định rằng các trường hợp đầu vào hỗn hợp nên được chuyển đổi. Tuy nhiên, tôi đã cập nhật câu trả lời đề cập toLowerCase. Chỉ cần lưu ý rằng nó sẽ phá vỡ các từ viết tắt. an HTML document: An HTML DocumentvsAn Html Document
Tom Kay

4
@Madbreaks Trong khi ví dụ ban đầu của bạn bị chiếm đoạt, bạn có một điểm tốt khi nói rằng đầu ra sẽ không thay đổi nếu đầu vào được viết hoa. Điều đó đang được nói, tôi cảm thấy câu trả lời như hiện tại (với gợi ý chỉnh sửa toLowerCase) linh hoạt / hữu ích hơn so với giả định về ý định của nhà phát triển. Phương thức này cũng phản ánh chức năng của các phương thức tích hợp tương tự của các ngôn ngữ khác như PHP ( ucwords) và Golang ( strings.Title). .MẠNG LƯỚI (TextInfo.ToTitleCase ) hoạt động thú vị cho trường hợp hỗn hợp, nhưng cũng sẽ không thay đổi chuỗi viết hoa.
Tom Kay

20

Không sử dụng regex chỉ để tham khảo:

String.prototype.toProperCase = function() {
  var words = this.split(' ');
  var results = [];
  for (var i = 0; i < words.length; i++) {
    var letter = words[i].charAt(0).toUpperCase();
    results.push(letter + words[i].slice(1));
  }
  return results.join(' ');
};

console.log(
  'john smith'.toProperCase()
)


Cảm ơn các giải pháp regex miễn phí!
lucifer63

20

var result =
  'this is very interesting'.replace(/\b[a-z]/g, (x) => x.toUpperCase())

console.log(result) // This Is Very Interesting


Chỉ cần một câu hỏi, cấu trúc () là để chỉ định một trận đấu trên bất kỳ chuỗi tùy chọn nào: đó là, (a | b) khớp với a hoặc b. Việc xây dựng (.) Làm gì?
Michael Blackburn

Đối với bất kỳ ai có cùng câu hỏi, nó xác định "blob" thay thế được sử dụng trong phần thay thế. Các đốm màu được đánh số liên tục, đầu tiên () được đặt vào $ 1, thứ hai thành $ 2. Tôi thấy trang web này hữu ích: javascript.info/tutorial/THER-expressions-methods
Michael Blackburn

Tôi không thể làm cho những thứ trên hoạt động được, nhưng tôi không phải là một phù thủy regex. Tôi đang sử dụng 'string'.replace(/^(.)(.*)/,function(s,p1,p2){return p1.toUpperCase()+p2;}) lại, điều này chỉ hoạt động để viết hoa chữ cái đầu tiên của chuỗi, nhưng trong trường hợp đó là những gì bạn cần, công trình xây dựng của tôi.
Michael Blackburn

1
Vì một số lý do, FF35 dường như bị nghẹt thở '$1'.toUpperCase(), dường như chữ hoa chưa được thực hiện vào thời điểm giá trị được gán. Làm việc xung quanh bằng cách sử dụng chức năng'string'.replace(/^(.){1}/,function(match) { return match.toUpperCase(); })
MrYellow 25/1/2015

Chào tất cả, câu trả lời đã được sửa! Tôi khá chắc chắn rằng nó đã hoạt động vào thời điểm tôi đăng nó ban đầu. Dù sao cũng cảm ơn cho đầu vào!
simo

17

Bạn có thể ngay lập tức toLowerCasechuỗi, và sau đó chỉ toUpperCaselà chữ cái đầu tiên của mỗi từ. Trở thành một lớp lót rất đơn giản:

function titleCase(str) {
  return str.toLowerCase().replace(/\b(\w)/g, s => s.toUpperCase());
}

console.log(titleCase('iron man'));
console.log(titleCase('iNcrEdible hulK'));


Tôi thích giải pháp này; đẹp và đơn giản. Dường như một chút CoffeeScript rơi vào câu trả lời của bạn ( s => s.toUpperCase()). Biến thể của tôi là làm những gì bạn đã làm, nhưng mở rộng đối tượng String (gây tranh cãi như vậy):Object.defineProperty(String.prototype, '_toProperCase', {value:function() {return this.toLowerCase().replace(/\b(\w)/g, function(t) {return t.toUpperCase()})}})
Waz

1
@Waz, cảm ơn vì những ý tưởng! Chỉ muốn làm rõ trên =>, đó là một chức năng mũi tên riêng (ES6), liên kết nhảy đến Tài liệu Mozillla trên đó cũng cung cấp một bảng hỗ trợ.
KevBot

16

Chỉ trong trường hợp bạn lo lắng về những từ phụ đó, bạn luôn có thể chỉ cho hàm biết những gì không viết hoa.

/**
 * @param String str The text to be converted to titleCase.
 * @param Array glue the words to leave in lowercase. 
 */
var titleCase = function(str, glue){
    glue = (glue) ? glue : ['of', 'for', 'and'];
    return str.replace(/(\w)(\w*)/g, function(_, i, r){
        var j = i.toUpperCase() + (r != null ? r : "");
        return (glue.indexOf(j.toLowerCase())<0)?j:j.toLowerCase();
    });
};

Hy vọng điều này sẽ giúp bạn ra ngoài.

biên tập

Nếu bạn muốn xử lý các từ keo hàng đầu, bạn có thể theo dõi biến này với thêm một biến:

var titleCase = function(str, glue){
    glue = !!glue ? glue : ['of', 'for', 'and', 'a'];
    var first = true;
    return str.replace(/(\w)(\w*)/g, function(_, i, r) {
        var j = i.toUpperCase() + (r != null ? r : '').toLowerCase();
        var result = ((glue.indexOf(j.toLowerCase()) < 0) || first) ? j : j.toLowerCase();
        first = false;
        return result;
    });
};

2
Bạn có thể nổ một chuỗi thành một mảng. Vì vậy, chúng ta có thể có giới từ Bồ Đào Nha, Tây Ban Nha, Ý và Pháp:glue ='de|da|del|dos|do|das|des|la|della|delli'.split('|');
Junior Mayhé

Điều này sẽ không đảm bảo viết hoa của từ đầu tiên; tức là and another thingtrở thành and Another Thing. Chỉ cần một cách thanh lịch để luôn viết hoa từ đầu tiên.
Brad Koch

@BradKoch - phần đệm có khoảng trắng để bạn sử dụng 'và', 'de', v.v. làm từ tìm kiếm, sau đó 'And Another And Another' sẽ thay thế thành 'And Another and Another'.
Yimin Rong

tốt ngoại trừ nó viết hoa văn bản sau 'và - như H'Dy hoặc Number-One
luky

Thay vì sử dụng toán tử ternary, bạn chỉ có thể sử dụng dự phòng: keo = keo | | ['của', 'cho', 'và', 'a'];
tm2josep

14

Nếu regex được sử dụng trong các giải pháp trên khiến bạn bối rối, hãy thử mã này:

function titleCase(str) {
  return str.split(' ').map(function(val){ 
    return val.charAt(0).toUpperCase() + val.substr(1).toLowerCase();
  }).join(' ');
}

yêu nó! không chuyển đổi thành mảng.
neelmeg

1
uhhh ... split không chuyển đổi nó thành một mảng, bạn chỉ không thấy nó rõ ràng vì mapcó nghĩa là bạn không phải sử dụng []ký hiệu
MalcolmOcean

2
Điều này giống như câu trả lời của a8m từ 2 năm trước.
Michael - Clay Shirky ở đâu

1
Phá vỡ cho đầu vào char đơn.
Madbreaks

1
@AlexChaffee kiểm tra lịch sử sửa đổi. a8m không sử dụng chức năng mũi tên trong câu trả lời ban đầu.
Cảm ơn bạn

9

Tôi đã thực hiện chức năng này có thể xử lý tên cuối cùng (vì vậy đây không phải là trường hợp tiêu đề) như "McDonald" hoặc "MacDonald" hoặc "O'Toole" hoặc "D'Orazio". Tuy nhiên, nó không xử lý tên tiếng Đức hoặc tiếng Hà Lan bằng "van" hoặc "von" thường ở dạng chữ thường ... Tôi tin rằng "de" thường là chữ thường, chẳng hạn như "Robert de Niro". Những điều này vẫn sẽ phải được giải quyết.

function toProperCase(s)
{
  return s.toLowerCase().replace( /\b((m)(a?c))?(\w)/g,
          function($1, $2, $3, $4, $5) { if($2){return $3.toUpperCase()+$4+$5.toUpperCase();} return $1.toUpperCase(); });
}

1
+1 cho nhận thức tên. Mặc dù vậy, không xử lý "macy" chính xác.
brianary

Đây là chức năng duy nhất xử lý chính xác việc chuyển chữ hoa và chữ thường thành trường hợp chính xác và nhận thấy tên viết tắt như "Quần đảo Virgin thuộc Hoa Kỳ".
Rodrigo Polo

Bạn có thể giải macyquyết vấn đề bằng cách đặt một cái nhìn tiêu cực vào đó để \b((m)(a?c))?(\w)trở thành\b((m)(a?c))?(\w)(?!\s)
Ste

8
var toMatch = "john w. smith";
var result = toMatch.replace(/(\w)(\w*)/g, function (_, i, r) {
      return i.toUpperCase() + (r != null ? r : "");
    }
)

Có vẻ như đã hoạt động ... Đã thử nghiệm với những điều trên, "con cáo nhanh màu nâu, con cáo? file1.txt ".

Nếu bạn muốn 2Nd thay vì thứ 2, bạn có thể thay đổi thành /([a-z])(\w*)/g .

Hình thức đầu tiên có thể được đơn giản hóa như:

function toTitleCase(toTransform) {
  return toTransform.replace(/\b([a-z])/g, function (_, initial) {
      return initial.toUpperCase();
  });
}

7

Thử cái này

String.prototype.toProperCase = function(){
    return this.toLowerCase().replace(/(^[a-z]| [a-z]|-[a-z])/g, 
        function($1){
            return $1.toUpperCase();
        }
    );
};

Thí dụ

var str = 'john smith';
str.toProperCase();

7

Nếu bạn có thể sử dụng các thư viện của bên thứ ba trong mã của mình thì lodash có chức năng trợ giúp cho chúng tôi.

https://lodash.com/docs/4.17.3#startCase

_.startCase('foo bar');
// => 'Foo Bar'

_.startCase('--foo-bar--');
// => 'Foo Bar'
 
_.startCase('fooBar');
// => 'Foo Bar'
 
_.startCase('__FOO_BAR__');
// => 'FOO BAR'


7

Hãy thử cách này, cách ngắn nhất:

str.replace(/(^[a-z])|(\s+[a-z])/g, txt => txt.toUpperCase());

7

ES 6

str.split(' ')
   .map(s => s.slice(0, 1).toUpperCase() + s.slice(1).toLowerCase())
   .join(' ')

khác

str.split(' ').map(function (s) {
    return s.slice(0, 1).toUpperCase() + s.slice(1).toLowerCase();
}).join(' ')

Chỉ cần ngẩng cao đầu, có lẽ nên là s.slice(0, 1).toUpperCase()nếu bạn vẫn muốn lá thư đầu tiên đó.
WindsofTime

@jssridhar bạn cũng nên sửa mã trong ES6.
caiosm1005

1
str
Phá

@jssridhar có thể tốt hơn cho chúng tôi .charAt(0).toUpperCase().
roydukkey

2
trùng lặp câu trả lời của a8m
Cảm ơn bạn vào

6

Hầu hết các câu trả lời này dường như bỏ qua khả năng sử dụng metacharacter ranh giới từ (\ b). Một phiên bản ngắn hơn của câu trả lời của Greg Dean sử dụng nó:

function toTitleCase(str)
{
    return str.replace(/\b\w/g, function (txt) { return txt.toUpperCase(); });
}

Hoạt động cho các tên gạch nối như Jim-Bob quá.


2
Là một giải pháp một phần thanh lịch nhưng không hoạt động với các chuỗi dấu hoặc chữ hoa. Tôi nhận được "Sofía Vergara" => "SofíA Vergara" hoặc "Sofía VERGARA" => "SofíA VERGARA". Trường hợp thứ hai có thể được giải quyết bằng hàm áp dụng .toLowerCase () trước .replace (...). Trường hợp đầu tiên cần tìm một biểu thức chính quy đúng.
Aserware

2
Hmm, có vẻ như là một lỗi trong quá trình triển khai regex, tôi nghĩ các ký tự có dấu phải là ký tự từ (mặc dù bạn đúng, vì nó không hoạt động cho những trường hợp đó).
lewax00

\wchỉ bao gồm các ký tự [A-Za-z0-9_], không phải tất cả các chữ cái. Cho rằng bạn cần sử dụng danh mục Unicode \p{L}. Bạn sẽ cần công cụ /usửa đổi (xem tại đây ) và một giải pháp khác \b, chỉ hoạt động giữa \W\w(xem tại đây )
cmbuckley

6

Tôi nghĩ đơn giản nhất là sử dụng css.

function format_str(str) {
    str = str.toLowerCase();
    return '<span style="text-transform: capitalize">'+ str +'</span>';
}

Tôi đã cập nhật mã và kiểm tra nó. Nó nên hoạt động ngay bây giờ.
wonderim

Bạn chỉ có thể sử dụng CSS trong một phần nhỏ môi trường mà JS được sử dụng, vì vậy giải pháp này không khả thi. Ngoài ra phong cách nội tuyến nên tránh bằng mọi giá.
Madbreaks

5

Sử dụng /\S+/gđể hỗ trợ dấu phụ:

function toTitleCase(str) {
  return str.replace(/\S+/g, str => str.charAt(0).toUpperCase() + str.substr(1).toLowerCase());
}

console.log(toTitleCase("a city named örebro")); // A City Named Örebro

Tuy nhiên: " s unlight ( y ellow )" " S unlight ( y ellow )"


5

Tôi muốn thêm câu trả lời của riêng mình vì tôi cần một toTitleCasechức năng mạnh mẽ có tính đến các quy tắc ngữ pháp được liệt kê ở đây (bài viết được đề xuất của Google). Có nhiều quy tắc khác nhau phụ thuộc vào độ dài của chuỗi đầu vào. Dưới đây là chức năng + kiểm tra đơn vị.

Hàm này cũng hợp nhất khoảng trắng và xóa các ký tự đặc biệt (sửa đổi biểu thức chính quy cho nhu cầu của bạn)

Chức năng toTitleCase

const toTitleCase = (str) => {
  const articles = ['a', 'an', 'the'];
  const conjunctions = ['for', 'and', 'nor', 'but', 'or', 'yet', 'so'];
  const prepositions = [
    'with', 'at', 'from', 'into','upon', 'of', 'to', 'in', 'for',
    'on', 'by', 'like', 'over', 'plus', 'but', 'up', 'down', 'off', 'near'
  ];

  // The list of spacial characters can be tweaked here
  const replaceCharsWithSpace = (str) => str.replace(/[^0-9a-z&/\\]/gi, ' ').replace(/(\s\s+)/gi, ' ');
  const capitalizeFirstLetter = (str) => str.charAt(0).toUpperCase() + str.substr(1);
  const normalizeStr = (str) => str.toLowerCase().trim();
  const shouldCapitalize = (word, fullWordList, posWithinStr) => {
    if ((posWithinStr == 0) || (posWithinStr == fullWordList.length - 1)) {
      return true;
    }

    return !(articles.includes(word) || conjunctions.includes(word) || prepositions.includes(word));
  }

  str = replaceCharsWithSpace(str);
  str = normalizeStr(str);

  let words = str.split(' ');
  if (words.length <= 2) { // Strings less than 3 words long should always have first words capitalized
    words = words.map(w => capitalizeFirstLetter(w));
  }
  else {
    for (let i = 0; i < words.length; i++) {
      words[i] = (shouldCapitalize(words[i], words, i) ? capitalizeFirstLetter(words[i], words, i) : words[i]);
    }
  }

  return words.join(' ');
}

Kiểm tra đơn vị để đảm bảo tính chính xác

import { expect } from 'chai';
import { toTitleCase } from '../../src/lib/stringHelper';

describe('toTitleCase', () => {
  it('Capitalizes first letter of each word irrespective of articles, conjunctions or prepositions if string is no greater than two words long', function(){
    expect(toTitleCase('the dog')).to.equal('The Dog'); // Capitalize articles when only two words long
    expect(toTitleCase('for all')).to.equal('For All'); // Capitalize conjunctions when only two words long
    expect(toTitleCase('with cats')).to.equal('With Cats'); // Capitalize prepositions when only two words long
  });

  it('Always capitalize first and last words in a string irrespective of articles, conjunctions or prepositions', function(){
    expect(toTitleCase('the beautiful dog')).to.equal('The Beautiful Dog');
    expect(toTitleCase('for all the deadly ninjas, be it so')).to.equal('For All the Deadly Ninjas Be It So');
    expect(toTitleCase('with cats and dogs we are near')).to.equal('With Cats and Dogs We Are Near');
  });

  it('Replace special characters with space', function(){
    expect(toTitleCase('[wolves & lions]: be careful')).to.equal('Wolves & Lions Be Careful');
    expect(toTitleCase('wolves & lions, be careful')).to.equal('Wolves & Lions Be Careful');
  });

  it('Trim whitespace at beginning and end', function(){
    expect(toTitleCase(' mario & Luigi superstar saga ')).to.equal('Mario & Luigi Superstar Saga');
  });

  it('articles, conjunctions and prepositions should not be capitalized in strings of 3+ words', function(){
    expect(toTitleCase('The wolf and the lion: a tale of two like animals')).to.equal('The Wolf and the Lion a Tale of Two like Animals');
    expect(toTitleCase('the  three Musketeers  And plus ')).to.equal('The Three Musketeers and Plus');
  });
});

Xin lưu ý rằng tôi đang loại bỏ khá nhiều ký tự đặc biệt khỏi chuỗi được cung cấp. Bạn sẽ cần phải điều chỉnh regex để giải quyết các yêu cầu của dự án của bạn.


Tôi thích giải pháp này vì nó thực sự quan tâm đến trường hợp tiêu đề. Đó không phải là "Cuốn theo chiều gió" mà là "Cuốn theo chiều gió"
russellmania

5
"john f. kennedy".replace(/\b\S/g, t => t.toUpperCase())

1
Hoạt động cho mẫu và o'henry, nhưng làm những thứ kỳ lạ với horse's mouth.
Michael - Clay Shirky ở đâu

"john f. kennEdy".toLowerCase().replace(/\b\S/g, t => t.toUpperCase())tốt hơn 🤔
w3debugger

Không muốn chỉnh sửa câu trả lời của @ ProSense: \b\Slà các lớp ký tự đặc biệt biểu thị ranh giới từ Lời và ranh giới, ký tự không phải khoảng trắng. Vì vậy, regex khớp với mọi ký tự đơn theo ranh giới từ và viết hoa ký tự đó bằng cách áp dụng hàm mũi tên đã cho.
Jens

4

Sử dụng giải pháp "lewax00", tôi đã tạo ra giải pháp đơn giản này bắt buộc "w" bắt đầu bằng dấu cách hoặc "w" khởi tạo từ, nhưng không thể xóa các khoảng trắng trung gian bổ sung.

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

Kết quả là "Sofía Vergara".


4

Đây là chức năng của tôi là chăm sóc các ký tự có dấu (quan trọng đối với tiếng Pháp!) Và có thể bật / tắt việc xử lý các ngoại lệ thấp. Mong rằng sẽ giúp.

String.prototype.titlecase = function(lang, withLowers = false) {
    var i, string, lowers, uppers;

    string = this.replace(/([^\s:\-'])([^\s:\-']*)/g, function(txt) {
        return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
    }).replace(/Mc(.)/g, function(match, next) {
        return 'Mc' + next.toUpperCase();
    });

    if (withLowers) {
        if (lang == 'EN') {
            lowers = ['A', 'An', 'The', 'At', 'By', 'For', 'In', 'Of', 'On', 'To', 'Up', 'And', 'As', 'But', 'Or', 'Nor', 'Not'];
        }
        else {
            lowers = ['Un', 'Une', 'Le', 'La', 'Les', 'Du', 'De', 'Des', 'À', 'Au', 'Aux', 'Par', 'Pour', 'Dans', 'Sur', 'Et', 'Comme', 'Mais', 'Ou', 'Où', 'Ne', 'Ni', 'Pas'];
        }
        for (i = 0; i < lowers.length; i++) {
            string = string.replace(new RegExp('\\s' + lowers[i] + '\\s', 'g'), function(txt) {
                return txt.toLowerCase();
            });
        }
    }

    uppers = ['Id', 'R&d'];
    for (i = 0; i < uppers.length; i++) {
        string = string.replace(new RegExp('\\b' + uppers[i] + '\\b', 'g'), uppers[i].toUpperCase());
    }

    return string;
}

4

Chúng tôi đã có một cuộc thảo luận tại văn phòng ở đây và chúng tôi nghĩ rằng việc cố gắng tự động sửa cách mọi người nhập tên theo cách hiện tại mà bạn muốn làm là có nhiều vấn đề có thể xảy ra.

Chúng tôi đã đưa ra một số trường hợp trong đó các loại viết hoa tự động khác nhau và chúng chỉ dành cho tên tiếng Anh, mỗi ngôn ngữ có độ phức tạp riêng.

Các vấn đề viết hoa chữ cái đầu tiên của mỗi tên:

• Các từ viết tắt như IBM không được phép nhập vào, sẽ biến thành Ibm.

• Tên McDonald sẽ biến thành Mcdonald không chính xác, điều tương tự cũng là MacDonald.

• Những tên nòng đôi như Marie-Tonks sẽ bị biến thành Marie-tonks.

• Những tên như O'Connor sẽ biến thành O'connor.

Đối với hầu hết những điều này, bạn có thể viết các quy tắc tùy chỉnh để đối phó với nó, tuy nhiên, điều này vẫn có vấn đề với các từ viết tắt như trước đây và bạn gặp phải một vấn đề mới:

• Thêm một quy tắc để sửa các tên bằng Mac như MacDonald, các tên bị phá vỡ như Macy sẽ biến nó thành MacY.

Giải pháp duy nhất mà chúng tôi đưa ra là không bao giờ sai là viết hoa mỗi chữ cái là phương pháp vũ lực mà DBS dường như cũng sử dụng.

Vì vậy, nếu bạn muốn tự động hóa quy trình thì tốt nhất là không thể thực hiện được nếu không có từ điển của mỗi tên và từ và cách viết hoa, nếu bạn không có quy tắc bao gồm mọi thứ thì đừng sử dụng nó. sẽ chỉ gây khó chịu cho người dùng của bạn và nhắc những người muốn nhập tên của họ một cách chính xác để đi nơi khác.


4

Đây là một giải pháp khác sử dụng css (và javascript, nếu văn bản bạn muốn chuyển đổi là chữ hoa):

html

<span id='text'>JOHN SMITH</span>

js

var str = document.getElementById('text').innerHtml;
var return_text = str.toLowerCase();

css

#text{text-transform:capitalize;}

3

Đối với những người trong chúng ta sợ biểu thức thông thường (lol):

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


3

Giải pháp một dòng của tôi:

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

Sau đó, bạn có thể gọi phương thức capitalizeWords()trên bất kỳ chuỗi nào. Ví dụ:

var myS = "this actually works!";
myS.capitalizeWords();

>>> This Actually Works

Giải pháp khác của tôi:

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(" ");
};

Sau đó, bạn có thể gọi phương thức capitalizeWords()trên bất kỳ chuỗi nào. Ví dụ:

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

>>> This One Works Too

Giải pháp thay thế dựa trên câu trả lời của Greg Dean:

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

Sau đó, bạn có thể gọi phương thức capitalizeWords()trên bất kỳ chuỗi nào. Ví dụ:

var myString = "yes and no";
myString.capitalizeWords()

>>> Yes And No

3

Ngạc nhiên khi thấy không ai đề cập đến việc sử dụng tham số nghỉ ngơi. Đây là một lớp lót đơn giản sử dụng các tham số ES6 Rest.

let str="john smith"
str=str.split(" ").map(([firstChar,...rest])=>firstChar.toUpperCase()+rest.join("").toLowerCase()).join(" ")
console.log(str)


2

Điều này dựa trên giải pháp của tôi cho "Trường hợp tiêu đề" Bonfire của FreeCodeCamp , yêu cầu bạn trước tiên chuyển đổi chuỗi đã cho thành tất cả chữ thường và sau đó chuyển đổi mọi ký tự tiến hành khoảng trắng thành chữ hoa.

Không sử dụng regex:

function titleCase(str) {
 return str.toLowerCase().split(' ').map(function(val) { return val.replace(val[0], val[0].toUpperCase()); }).join(' ');
}
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.