Konversi string ke judul huruf dengan JavaScript

549

Apakah ada cara sederhana untuk mengubah string ke judul kasus? Misalnya john smithmenjadi John Smith. Saya tidak mencari sesuatu yang rumit seperti solusi John Resig , hanya (semoga) semacam satu atau dua liner.

MDCore
sumber
Ada berbagai metode, apakah kami memiliki beberapa statistik kinerja?
theAnubhav
Harap chech jawaban singkat ini stackoverflow.com/a/57689168/10373693 Saya harap itu akan menjadi jawaban yang Anda cari.
Abhishek Kumar

Jawaban:

740

Coba ini:

    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>

Greg Dean
sumber
14
Adakah yang bisa menjelaskan, mengapa \w\S*digunakan, bukan \w+atau \w*misalnya? Saya tidak tahu, mengapa Anda ingin memasukkan apa pun selain spasi dan karenanya mengubah Jim-Bob menjadi Jim-bob .
martinczerwi
5
@martinCzerwi \w\S*juga menyebabkan Jim-bobmasalah pada kami. Menggunakan \w*diselesaikan ini.
Bouke
14
/([^\W_]+[^\s-]*) */gmemecahkan Jim-Bobmasalah, yaitu:jim-bob --> Jim-Bob
recursion.ninja
15
Jika jim-bob --> Jim-Bobitu keinginan Anda, mungkin sebaiknya Anda lakukan /\b\w+/g. Contoh:str.replace(/\b\w+/g,function(s){return s.charAt(0).toUpperCase() + s.substr(1).toLowerCase();});
vol7ron
3
\w\S*digunakan sebagai ganti \w+atau \w*agar kata-kata seperti Don'ttidak dapat dimodifikasi Don'T, tetapi seperti yang orang lain katakan \w\S*menyebabkan masalah dengan kata-kata yang ditulis dgn tanda penghubung.
doubleDown
198

Cara yang sedikit lebih elegan, mengadaptasi fungsi Greg Dean:

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

Sebut saja seperti:

"pascal".toProperCase();
Tuan
sumber
3
Perlu diingat jika Anda memiliki pengguna dengan tanda hubung di nama mereka dan mereka masukkan Jo-Ann Smith, kode ini akan mengubahnya menjadi Jo-ann Smith(perhatikan huruf kecil adi Ann).
dbau
18
@daniellmb Mengapa ia tidak mengubah prototipe String? Saya pikir ini solusi yang baik. Pikirkan kelas terbuka ruby, sangat sah untuk menambahkan fungsi ke kelas yang ada dan diterima secara luas.
marco-fiset
97
@ marco-fiset Karena tidak bermain baik dengan yang lain! Hal-hal buruk terjadi ketika Anda memiliki 2 perpustakaan yang sama-sama mencoba untuk memodifikasi objek JavaScript asli dengan perubahan yang tidak kompatibel. Bayangkan jika jQuery dan Google Maps mengikuti pola desain ini, Anda tidak bisa memiliki keduanya di halaman yang sama.
daniellmb
5
@daniellmb Poin yang sangat bagus. Awalan nama metode harus membantu menghindari hal ini, karena akan membuat metode tidak dapat dihitung.
mikemaccana
60
Saya merasa seperti pernyataan "jangan modifikasi objek JavaScript asli" seperti "tidak pernah menggunakan goto" atau "eval is evil". Ada banyak kasus di mana itu ok. Jika Anda memiliki kendali penuh atas proyek Anda dan tentu saja tidak berencana merilisnya sebagai perpustakaan, saya tidak melihat masalah dengan metode ini.
FoxMulder900
175

Cobalah untuk menerapkan gaya CSS transformasi teks ke kontrol Anda.

misalnya: (text-transform: capitalize);

Hanya gunakan pendekatan JS jika benar-benar diperlukan.

Talha Ashfaque
sumber
36
-1. Css ini berfungsi, tetapi tidak berfungsi seperti yang diharapkan kebanyakan orang karena jika teks dimulai dengan huruf kapital semua, tidak ada efek. webmasterworld.com/forum83/7506.htm
whitneyland
2
@ Akshar: Aturan huruf kecil akan diganti dengan aturan judul kasus. Karena css tidak mengubah konten sumber, efeknya adalah aturan huruf kecil dihapus (meninggalkan konten sumber dalam semua huruf besar) dan kemudian aturan titlecase akan diterapkan (tidak melakukan apa-apa).
dokkaebi
42
JS digunakan di luar browser.
mikemaccana
4
Pertanyaannya adalah: "Apakah ada cara sederhana untuk mengubah string menjadi case title?" . Jawaban ini tidak mengonversi string. Ini adalah gaya yang diterapkan di atas sebuah string.
kingPuppy
Jika Anda ingin data dalam database Anda menjadi bersih, sehingga dapat digunakan dengan bersih saat beralih ke layanan pihak ke-3 atau diekspor ke CSV, maka CSS sebenarnya bukan pilihan. CSS ditujukan untuk kosmetik, dan meskipun telah banyak berkembang selama bertahun-tahun dan Anda dapat menggunakannya untuk memecahkan masalah seperti ini, solusinya tetap kosmetik dan tidak memecahkan masalah yang mendasarinya.
Adam Reis
118

Ini versi saya, IMO juga mudah dimengerti dan elegan.

var str = "foo bar baz"

console.log(

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

)
// returns "Foo Bar Baz"

a8m
sumber
3
Sebagai alternatif, Anda dapat menggunakan huruf kecil pada substring dalam pemetaan:str.split(' ').map(i => i[0].toUpperCase() + i.substring(1).toLowerCase()).join(' ')
Dave Land
5
Saya tidak setuju dengan panggilan .toLowerCase(). Nama-nama seperti "McDonald" atau akronim seperti "ASAP" harus mempertahankan karakter huruf besar mereka. Jika seseorang benar-benar mengirimkan string seperti "heLLO", aplikasi seharusnya tidak menganggap huruf besar salah.
Thomas Higginbotham
1
@ThomasHigginbotham Bagaimana dengan ini? 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
Ya, memberikan opsi untuk memaksa huruf kecil akan lebih disukai.
Thomas Higginbotham
1
Ini akan pecah jika strkarakter tunggal.
Madbreaks
103

Inilah fungsi saya yang mengonversi ke case title tetapi juga mempertahankan akronim yang didefinisikan sebagai huruf besar dan kata-kata kecil sebagai huruf kecil:

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

Sebagai contoh:

"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:"
Geoffrey Booth
sumber
1
Saya suka milik Anda, saya juga mengalami masalah ketika berhadapan dengan angka romawi ... hanya menambalnya dengan I, II, III, IV, dll.
Marcelo
2
Tetap. Regex di baris ketiga telah diubah dari /\w\S*/gmenjadi /([^\W_]+[^\s-]*) */gper @ awashburn komentar di atas untuk mengatasi ini.
Geoffrey Booth
2
Apakah ada keuntungan yang bisa diperoleh dengan menggunakan pola regex Anda /\b\w+/g, yang menurut saya lebih cepat dipahami?
Michael - Di mana Clay Shirky
2
Bukannya aku bisa melihat, aku hanya mengambil saran komentator lain untuk memecahkan masalah kata ditulis dgn tanda penghubung; tetapi regex Anda tampaknya berfungsi dengan baik, dan kesederhanaan selalu lebih baik. Untuk anak cucu dan pengunjung masa depan ke posting ini, saya baru saja mengubah regex di baris ketiga dari /([^\W_]+[^\s-]*) */gmenjadi /\b\w+/gper @ Michael's komentar; tolong beri komentar jika Anda menemukan kasus di mana regex yang lebih rumit diperlukan.
Geoffrey Booth
1
Saya mengubah regex baris ke-3 /\b[\w-\']+/guntuk memungkinkan kata ditulis dgn tanda penghubung dan apostrof dalam kata-kata.
Shamasis Bhattacharya
47

Saya lebih suka yang berikut daripada jawaban lainnya. Hanya cocok dengan huruf pertama dari setiap kata dan huruf besar. Kode lebih sederhana, lebih mudah dibaca dan lebih sedikit byte. Ini mempertahankan huruf kapital yang ada untuk mencegah akronim yang menyimpang. Namun Anda selalu dapat memanggil toLowerCase()string Anda terlebih dahulu.

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

Anda dapat menambahkan ini ke prototipe string yang memungkinkan Anda melakukan hal 'my string'.toTitle()berikut:

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

Contoh:

Tom Kay
sumber
3
Ini bahkan lebih baik sebagai lambdaconst titleCase = (str) => str.replace(/\b\S/g, t => t.toUpperCase());
0xcaff
Saya tidak ingin merusak IE, tapi ya jika aplikasi ini tidak peka terhadap peramban, ini bisa lebih pendek.
Tom Kay
Ini hanya solusi parsial - op yang menanyakan cara mengonversi string menjadi case title. Jawaban ini tidak mencukupi untuk input seperti NoT qUiITe.
Madbreaks
@Madbreaks Pertanyaan ini tidak menyatakan bahwa input case campuran harus dikonversi. Namun, saya telah memperbarui jawaban yang menyebutkan toLowerCase. Ketahuilah bahwa itu akan merusak akronim. an HTML document: An HTML DocumentvsAn Html Document
Tom Kay
4
@Madbreaks Sementara contoh awal Anda dibuat, Anda membuat poin yang baik dalam menyatakan bahwa output tidak akan berubah jika input dikapitalisasi. Yang sedang berkata, saya merasa jawabannya apa adanya (dengan saran sunting toLowerCase) lebih fleksibel / berguna daripada yang mengasumsikan niat pengembang. Metode ini juga mencerminkan fungsionalitas metode ucwordsbawaan serupa dari bahasa lain seperti PHP ( ) dan Golang ( strings.Title). .NET ( TextInfo.ToTitleCase) menariknya berfungsi untuk case campuran, tetapi juga tidak akan mengubah string dengan huruf kapital penuh.
Tom Kay
20

Tanpa menggunakan regex hanya untuk referensi:

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

Mike
sumber
Terima kasih atas solusi regex gratis!
lucifer63
20

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

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

simo
sumber
Hanya pertanyaan, konstruk () adalah untuk menentukan kecocokan pada urutan opsi mana pun: yaitu, (a | b) cocok dengan a atau b. Apa yang konstruksi (.) Lakukan?
Michael Blackburn
Bagi siapa pun yang memiliki pertanyaan yang sama, itu mendefinisikan "gumpalan" pengganti yang digunakan di bagian penggantian. Gumpalan dinomori secara berurutan, yang pertama () dimasukkan ke dalam $ 1, yang kedua menjadi $ 2. Saya menemukan situs ini bermanfaat: javascript.info/tutorial/regular-expressions-methods
Michael Blackburn
Saya tidak bisa mendapatkan cara di atas untuk bekerja, tapi saya jauh dari penyihir regex. Saya menggunakan 'string'.replace(/^(.)(.*)/,function(s,p1,p2){return p1.toUpperCase()+p2;}) lagi, ini hanya berfungsi untuk huruf besar dari string, tetapi jika itu yang Anda butuhkan, konstruksi saya berfungsi.
Michael Blackburn
1
Untuk beberapa alasan FF35 tampaknya tersedak '$1'.toUpperCase(), tampaknya huruf besar belum selesai pada saat nilai ditugaskan. Bekerja di sekitar dengan menggunakan fungsi'string'.replace(/^(.){1}/,function(match) { return match.toUpperCase(); })
MrYellow
Hai Semua, jawabannya sudah pasti! Saya cukup yakin itu berfungsi pada saat saya mempostingnya. Pokoknya terima kasih atas masukannya!
Simo
17

Anda dapat langsung toLowerCasemembuat string, dan kemudian hanya toUpperCasehuruf pertama dari setiap kata. Menjadi 1 liner yang sangat sederhana:

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

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

KevBot
sumber
Saya suka solusi ini; bagus dan sederhana. Sepertinya sedikit CoffeeScript menyelipkan jawaban Anda ( s => s.toUpperCase()). Varian saya adalah melakukan apa yang telah Anda lakukan, tetapi memperluas objek String (sama kontroversialnya dengan itu):Object.defineProperty(String.prototype, '_toProperCase', {value:function() {return this.toLowerCase().replace(/\b(\w)/g, function(t) {return t.toUpperCase()})}})
Waz
1
@ Wah, terima kasih atas idenya! Hanya ingin mengklarifikasi =>, yaitu fungsi panah asli (ES6), tautan melompat ke Mozillla Docs pada mereka yang juga menyediakan tabel dukungan.
KevBot
16

Kalau-kalau Anda khawatir tentang kata-kata pengisi, Anda selalu dapat hanya memberitahu fungsi apa yang tidak untuk memanfaatkan.

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

Semoga ini bisa membantu Anda.

sunting

Jika Anda ingin menangani kata lem terkemuka, Anda dapat melacak ini dengan satu variabel lagi:

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;
    });
};
kompi
sumber
2
Anda bisa meledakkan string menjadi array. Jadi kita bisa memiliki preposisi portugis, Spanyol, Italia, dan Prancis:glue ='de|da|del|dos|do|das|des|la|della|delli'.split('|');
Junior Mayhé
Ini tidak akan memastikan kapitalisasi kata pertama; yaitu and another thingmenjadi and Another Thing. Hanya perlu cara yang elegan untuk selalu memanfaatkan huruf pertama.
Brad Koch
@BradKoch - pad dengan spasi sehingga Anda menggunakan 'dan', 'de', dll sebagai kata pencarian, lalu 'Dan Lain Dan Lain' akan menggantikan menjadi 'Dan Lain dan Lain'.
Yimin Rong
bagus kecuali huruf besar juga teks setelah 'dan - seperti H'Dy atau Number-One
luky
Alih-alih menggunakan operator ternary Anda hanya bisa menggunakan fallback: lem = lem || ['dari', 'untuk', 'dan', 'a'];
tm2josep
14

Jika regex yang digunakan dalam solusi di atas membuat Anda bingung, coba kode ini:

function titleCase(str) {
  return str.split(' ').map(function(val){ 
    return val.charAt(0).toUpperCase() + val.substr(1).toLowerCase();
  }).join(' ');
}
immazharkhan
sumber
suka! tidak ada konversi ke array.
neelmeg
1
uhhh ... split tidak mengubahnya menjadi sebuah array, Anda hanya tidak melihatnya sebagai jelas karena mapberarti Anda tidak perlu menggunakan []notasi
MalcolmOcean
2
Ini sama dengan jawaban a8m dari 2 tahun sebelumnya.
Michael - Di mana Clay Shirky
1
Istirahat untuk input char tunggal.
Madbreaks
1
@AlexChaffee memeriksa riwayat revisi. a8m tidak menggunakan fungsi panah pada jawaban asli.
Terima kasih
9

Saya membuat fungsi ini yang dapat menangani nama belakang (jadi bukan judulnya) seperti "McDonald" atau "MacDonald" atau "O'Toole" atau "D'Orazio". Namun itu tidak menangani nama Jerman atau Belanda dengan "van" atau "von" yang sering kali dalam huruf kecil ... Saya percaya "de" sering kali lebih rendah juga seperti "Robert de Niro". Ini masih harus ditangani.

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(); });
}
Lwangaman
sumber
1
+1 untuk kesadaran nama. Namun, tidak menangani "macy" dengan benar.
brianary
Ini adalah satu-satunya fungsi yang menangani transformasi huruf besar dan huruf kecil dengan benar menjadi huruf besar dan yang memperhatikan inisial seperti "Kepulauan Virgin AS".
Rodrigo Polo
Anda dapat mengatasi macymasalah dengan menempatkan kepala pencarian negatif di sana sehingga \b((m)(a?c))?(\w)menjadi\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 : "");
    }
)

Tampaknya bekerja ... Diuji dengan di atas, "rubah cepat berwarna coklat, rubah? / Melompati ^ si malas! Anjing ..." dan "C: / file program / beberapa vendor / aplikasi kedua / a file1.txt ".

Jika Anda menginginkan 2Nd bukannya 2, Anda dapat mengubah ke /([a-z])(\w*)/g .

Bentuk pertama dapat disederhanakan sebagai:

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

Coba ini

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

Contoh

var str = 'john smith';
str.toProperCase();
Maxi Baez
sumber
7

Jika Anda dapat menggunakan perpustakaan pihak ketiga dalam kode Anda maka lodash memiliki fungsi pembantu bagi kami.

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'

waqas
sumber
7

Coba ini, cara terpendek:

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

ES 6

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

lain

str.split(' ').map(function (s) {
    return s.slice(0, 1).toUpperCase() + s.slice(1).toLowerCase();
}).join(' ')
jssridhar
sumber
Hanya kepala, mungkin harus s.slice(0, 1).toUpperCase()jika Anda masih menginginkan surat pertama itu.
WindsofTime
@ jssridhar Anda juga harus memperbaiki kode di ES6.
caiosm1005
1
Istirahat jika stradalah karakter tunggal
Madbreaks
@ jssridhar mungkin lebih baik bagi kita .charAt(0).toUpperCase().
roydukkey
2
duplikat jawaban a8m
Terima kasih
6

Sebagian besar jawaban ini tampaknya mengabaikan kemungkinan menggunakan kata batas metacharacter (\ b). Versi pendek dari jawaban Greg Dean memanfaatkannya:

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

Bekerja untuk nama yang ditulis dgn tanda penghubung seperti Jim-Bob juga.

lewax00
sumber
2
Merupakan solusi parsial yang elegan tetapi tidak bekerja dengan aksen atau string huruf besar. Saya mendapatkan "SofĂ­a Vergara" => "SofĂ­A Vergara" atau "SofĂ­a VERGARA" => "SofĂ­A VERGARA". Kasus kedua dapat diselesaikan dengan menerapkan fungsi .toLowerCase () sebelum .replace (...). Kasus pertama perlu menemukan ekspresi reguler yang tepat.
Asereware
2
Hmm, yang kelihatannya seperti bug dalam implementasi regex, saya akan berpikir karakter beraksen harus karakter kata (Anda benar, karena-apakah itu tidak berfungsi untuk kasus-kasus itu).
lewax00
\whanya menyertakan karakter [A-Za-z0-9_], tidak semua huruf. Untuk itu Anda harus menggunakan kategori Unicode \p{L}. Anda memerlukan /upengubah (lihat di sini ) dan solusi berbeda \b, yang hanya berfungsi di antara \Wdan \w(lihat di sini )
cmbuckley
6

Saya pikir yang paling sederhana adalah menggunakan css.

function format_str(str) {
    str = str.toLowerCase();
    return '<span style="text-transform: capitalize">'+ str +'</span>';
}
keajaiban
sumber
Saya memperbarui kode dan mengujinya. Itu seharusnya bekerja sekarang.
wondim
Anda hanya dapat menggunakan CSS di sebagian kecil dari lingkungan yang digunakan JS, sehingga solusi ini tidak layak. Gaya inline juga harus dihindari di semua biaya.
Madbreaks
5

Gunakan /\S+/guntuk mendukung diakritik:

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

Namun: " s unshine ( y ellow)" ⇒ " S unshine ( y ellow)"

le_m
sumber
5

Saya ingin menambahkan jawaban saya sendiri karena saya membutuhkan toTitleCasefungsi yang kuat yang memperhitungkan aturan tata bahasa yang tercantum di sini (artikel yang direkomendasikan Google). Ada berbagai aturan yang bergantung pada panjang string input. Di bawah ini adalah tes fungsi + unit.

Fungsi ini juga mengkonsolidasikan spasi putih dan menghapus karakter khusus (memodifikasi regex untuk kebutuhan Anda)

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

Unit Tes untuk Memastikan Kebenaran

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

Harap dicatat bahwa saya menghapus sedikit karakter khusus dari string yang disediakan. Anda perlu mengubah regex untuk memenuhi persyaratan proyek Anda.

momen dipol
sumber
Saya lebih suka solusi ini karena benar-benar menangani kasus judul. Ini bukan "Gone With The Wind" itu "Gone with the Wind"
russellmania
5
"john f. kennedy".replace(/\b\S/g, t => t.toUpperCase())
Pd bulan depan
sumber
1
Bekerja untuk sampel dan o'henry, tetapi melakukan hal-hal aneh dengan horse's mouth.
Michael - Di mana Clay Shirky
"john f. kennEdy".toLowerCase().replace(/\b\S/g, t => t.toUpperCase())lebih baik 🤔
w3debugger
Tidak ingin mengedit jawaban Proximo: \bdan \Sadalah kelas karakter khusus yang menunjukkan "batas kata" dan "tunggal, karakter bukan spasi. Jadi, regex cocok dengan setiap karakter tunggal mengikuti batas kata, dan memanfaatkan karakter itu dengan menerapkan fungsi panah yang diberikan.
Jens
4

Mengambil solusi "lewax00", saya menciptakan solusi sederhana ini yang memaksa "w" dimulai dengan spasi atau "w" yang memulai kata, tetapi tidak dapat menghapus ruang perantara tambahan.

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

Hasilnya adalah "SofĂ­a Vergara".

Asereware
sumber
4

Inilah fungsi saya yang menangani karakter beraksen (penting untuk bahasa Prancis!) Dan yang dapat menghidupkan / mematikan penanganan pengecualian yang lebih rendah. Semoga itu bisa membantu.

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;
}
Ouatataz
sumber
4

Kami telah melakukan diskusi di sini di kantor dan kami berpikir bahwa mencoba untuk secara otomatis memperbaiki cara orang memasukkan nama dengan cara yang Anda inginkan saat ini penuh dengan kemungkinan masalah.

Kami telah menemukan beberapa kasus di mana berbagai jenis kapitalisasi otomatis berantakan dan ini hanya untuk nama bahasa Inggris saja, setiap bahasa memiliki kompleksitasnya sendiri.

Masalah dengan huruf besar huruf pertama dari setiap nama:

• Akronim seperti IBM tidak diizinkan dimasukkan, akan berubah menjadi Ibm.

• Nama McDonald akan berubah menjadi Mcdonald yang tidak benar, hal yang sama juga MacDonald.

• Nama ganda laras seperti Marie-Tonks akan berubah menjadi Marie-tonks.

• Nama seperti O'Connor akan berubah menjadi O'connor.

Untuk sebagian besar dari ini, Anda dapat menulis aturan khusus untuk menghadapinya, namun, ini masih memiliki masalah dengan Akronim seperti sebelumnya dan Anda mendapatkan masalah baru:

• Menambahkan aturan untuk memperbaiki nama dengan Mac seperti MacDonald, akankah nama-nama seperti Macy mengubahnya menjadi MacY.

Satu-satunya solusi yang kami temukan yang tidak pernah salah adalah dengan memanfaatkan setiap huruf yang merupakan metode brute force yang tampaknya juga digunakan DBS.

Jadi, jika Anda ingin mengotomatiskan prosesnya, sama baiknya tidak mungkin dilakukan tanpa kamus dari setiap nama dan kata tunggal dan bagaimana itu harus dikapitalisasi, Jika Anda tidak memiliki aturan yang mencakup segala sesuatu jangan menggunakannya seperti itu hanya akan mengganggu pengguna Anda dan meminta orang yang ingin memasukkan nama mereka dengan benar untuk pergi ke tempat lain.

jjr2000
sumber
4

inilah solusi lain menggunakan css (dan javascript, jika teks yang ingin Anda ubah ada dalam huruf besar):

html

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

js

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

css

#text{text-transform:capitalize;}
Henrie
sumber
3

Bagi kita yang takut dengan ekspresi reguler (tertawa):

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

lashja
sumber
3

Solusi satu baris saya:

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

Kemudian, Anda dapat memanggil metode capitalizeWords()pada sembarang string. Sebagai contoh:

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

>>> This Actually Works

Solusi saya yang lain:

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

Kemudian, Anda dapat memanggil metode capitalizeWords()pada sembarang string. Sebagai contoh:

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

>>> This One Works Too

Solusi alternatif berdasarkan jawaban Greg Dean:

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

Kemudian, Anda dapat memanggil metode capitalizeWords()pada sembarang string. Sebagai contoh:

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

>>> Yes And No
Fouad Boukredine
sumber
3

Terkejut melihat tidak ada yang menyebutkan penggunaan parameter sisanya. Berikut ini adalah liner sederhana yang menggunakan parameter ES6 Rest.

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

kapil pandey
sumber
2

Ini didasarkan pada solusi saya untuk Bonfire "Title Case" FreeCodeCamp , yang mengharuskan Anda untuk terlebih dahulu mengonversi string yang diberikan ke semua huruf kecil dan kemudian mengonversi setiap karakter yang melanjutkan spasi ke huruf besar.

Tanpa menggunakan regex:

function titleCase(str) {
 return str.toLowerCase().split(' ').map(function(val) { return val.replace(val[0], val[0].toUpperCase()); }).join(' ');
}
Jamesy Dimmick May
sumber