JavaScript ile dizgiyi başlık durumuna dönüştürme


549

Bir dizeyi başlık durumuna dönüştürmenin basit bir yolu var mı? Örneğin john smitholur John Smith. John Resig'in çözümü gibi karmaşık bir şey aramıyorum , sadece (umarım) bir ya da iki astarlı.


Çeşitli yöntemler var, bazı performans istatistiklerimiz var mı?
theAnubhav

Lütfen bu kısa cevabı chech stackoverflow.com/a/57689168/10373693 Umarım aradığınız cevap bu olur.
Abhishek Kumar

Yanıtlar:


740

Bunu dene:

    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
Herkes açıklayabilir misiniz, neden \w\S*yerine kullanılır \w+ya da \w*örneğin? Bir şey ama boşluk ve bu nedenle değiştirmek isteyeyim neden bilmiyorum Jim-Bob için Jim-bob .
martinczerwi

5
@martinCzerwi \w\S*de Jim-bobbizim tarafımızdan soruna neden oldu . \w*Bunu kullanarak çözüldü.
Şubat'ta Bouke

14
/([^\W_]+[^\s-]*) */gJim-Bobsorunu çözer , yani:jim-bob --> Jim-Bob
recursion.ninja

15
Eğer jim-bob --> Jim-Bobarzunuz buysa, muhtemelen yapmalısınız /\b\w+/g. Örnek:str.replace(/\b\w+/g,function(s){return s.charAt(0).toUpperCase() + s.substr(1).toLowerCase();});
vol7ron

3
\w\S*gibi \w+veya bunun yerine kullanılır , ancak gibi \w*kelimeler Don'tdeğiştirilmez Don'T, ancak diğerlerinin işaret ettiği gibi \w\S*tireli kelimelerle ilgili sorunlara neden olur.
17:59

198

Greg Dean'in işlevini uyarlayan biraz daha zarif bir yol:

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

Şöyle çağırın:

"pascal".toProperCase();

3
Adlarında bir tire ile bir kullanıcı var ve onlar girerseniz unutmayın Jo-Ann Smithbu kod onları dönüştürmek, Jo-ann Smith(küçük harf notu aiçinde Ann).
dbau

18
@daniellmb Neden String prototipini değiştirmesin? Bence bu iyi bir çözüm. Yakut açık sınıfları düşünün, mevcut sınıflara işlev eklemek mükemmel bir şekilde geçerlidir ve yaygın olarak kabul edilir.
marco-fiset

97
@ marco-fiset Çünkü başkalarıyla iyi oynamıyor! Her ikisi de yerel JavaScript nesnelerini uyumsuz değişikliklerle değiştirmeye çalışan 2 kitaplığınız olduğunda kötü şeyler olur. JQuery ve Google Haritalar'ın bu tasarım desenini izleyip izlemediğini, her ikisinin de aynı sayfada bulunamayacağını düşünün.
daniellmb

5
@daniellmb Mükemmel bir nokta. Yöntem adının önekinin eklenmesi, yöntemi numaralandırılamaz hale getireceğinden, bundan kaçınmaya yardımcı olacaktır.
mikemaccana

60
"Yerel JavaScript nesnelerini değiştirme" deyimi "asla goto kullanma" veya "eval kötüdür" gibi hissediyorum. Tamam olduğu durumlarda bol miktarda vaka vardır. Projeniz üzerinde tam kontrole sahipseniz ve elbette onu bir kütüphane olarak yayınlamayı planlamıyorsanız, bu yöntemle ilgili hiçbir sorun görmüyorum.
FoxMulder900

175

Metin dönüşümü CSS stilini denetimlerinize uygulamayı deneyin .

Örneğin: (text-transform: capitalize);

JS yaklaşımını yalnızca kesinlikle gerekli olduğunda kullanın.


36
-1. Bu css çalışır, ancak çoğu insanın beklediği gibi çalışmaz, çünkü metin tüm büyük harfler olarak başlarsa, hiçbir etkisi yoktur. webmasterworld.com/forum83/7506.htm
whitneyland

2
@Akshar: Küçük harfli bir kural, bir büyük / küçük harf kuralıyla değiştirilir. Css kaynak içeriği değiştirmediğinden, etki küçük harf kuralının kaldırılmasıdır (kaynak içeriği tüm büyük harflerde bırakılır) ve sonra titlecase kuralı uygulanır (hiçbir şey yapılmaz).
dokkaebi

42
JS, tarayıcıların dışında kullanılır.
mikemaccana

4
Soru şuydu: "Bir dizeyi başlık durumuna dönüştürmenin basit bir yolu var mı?" . Bu yanıt bir dizeyi dönüştürmez. Bu, bir dizenin üstüne uygulanan bir stildir.
kingPuppy

Veritabanınızdaki verilerin temiz olmasını istiyorsanız, böylece üçüncü taraf hizmetlere geçerken veya CSV'ye aktarılırken temiz bir şekilde kullanılabilirse, CSS gerçekten bir seçenek değildir. CSS kozmetikler için tasarlanmıştır ve yıllar boyunca çok fazla büyürken ve bu tür sorunları çözmek için kullanabilirsiniz, çözüm kozmetik kalır ve altta yatan sorunu çözmez.
Adam Reis

118

İşte benim versiyonum, IMO da anlaşılması kolay ve zarif.

var str = "foo bar baz"

console.log(

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

)
// returns "Foo Bar Baz"


3
Alternatif olarak, alt dizeyi eşlemede küçük harflerle yazabilirsiniz:str.split(' ').map(i => i[0].toUpperCase() + i.substring(1).toLowerCase()).join(' ')
Dave Land

5
Aramaya katılmıyorum .toLowerCase(). "McDonald" gibi adlar veya "ASAP" gibi kısaltmalar büyük harf karakterlerini korumalıdır. Birisi "heLLO" gibi bir dizeden geçtiyse, uygulama büyük harflerin yanlış olduğunu varsaymamalıdır.
Thomas Higginbotham

1
@ThomasHigginbotham Buna ne dersin? 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

Evet, küçük harfleri zorlamak için bir seçenek sunmak tercih edilir.
Thomas Higginbotham

1
Bu strtek bir karakter ise kırılacaktır .
Madbreaks

103

Başlık büyük harf dönüştüren ama aynı zamanda tanımlanmış kısaltmaları büyük harf ve küçük kelimeleri küçük harf olarak koruyan fonksiyonum:

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

Örneğin:

"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
Sizinkini beğendim, Roma rakamlarıyla uğraşırken de sorunlarla karşılaşıyorum ... sadece I, II, III, IV
Marcelo

2
Sabit. Üçüncü satırdaki normal ifade, @ @ awashburn'un yukarıdaki yorumuna göre bu sorunu gidermek /\w\S*/giçin değiştirildi /([^\W_]+[^\s-]*) */g.
Geoffrey Booth

2
/\b\w+/gDaha hızlı anlaşılabilir bulduğum regex modelinizi kullanarak kazanılacak bir avantaj var mı ?
Michael - Clay Shirky

2
Görebildiğim için değil, sadece tireli sözcük problemini çözmek için başka bir yorumcunun önerisini alıyordum; ancak normal ifadeniz de aynı şekilde görünür ve sadelik her zaman daha iyidir. Bu yayına kuşaklar ve gelecek ziyaretçiler için sadece üçüncü satırda regex değişti /([^\W_]+[^\s-]*) */giçin /\b\w+/gMichael'ın yorumun @ per; daha karmaşık regex'in gerekli olduğu bir durum bulursanız lütfen yorum yapın.
Geoffrey Booth

1
Kısa çizgi /\b[\w-\']+/gkelimelere ve kesme işaretlerine izin vermek için 3. satır normal ifadesini değiştirdim .
Shamasis Bhattacharya

47

Diğer cevaplara göre aşağıdakileri tercih ederim. Her kelimenin sadece ilk harfiyle eşleşir ve büyük harf kullanır. Daha basit kod, okunması daha kolay ve daha az bayt. Kısaltmaların bozulmasını önlemek için mevcut büyük harfleri korur. Ancak toLowerCase()önce dizenizi her zaman arayabilirsiniz .

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

Bunu dize prototipinize şu şekilde ekleyebilirsiniz 'my string'.toTitle():

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

Misal:


3
Lambda olarak daha da güzelconst titleCase = (str) => str.replace(/\b\S/g, t => t.toUpperCase());
0xcaff

IE kırmak istemedim, ama evet uygulama eski tarayıcı duyarlı değilse daha kısa olabilir.
Tom Kay

Bu sadece kısmi bir çözümdür - op bir dizgiyi başlık büyüklüğüne nasıl dönüştüreceğini sordu. Bu cevap bunu gibi girdiler için başaramaz NoT qUiITe.
Madbreaks

@Madbreaks Soru, karışık vaka girişlerinin dönüştürülmesini şart koşmadı. Ancak, ben cevap cevap güncelledik toLowerCase. Kısaltmaları kıracağını unutmayın. an HTML document: An HTML DocumentvsAn Html Document
Tom Kay

4
@Madbreaks İlk örneğiniz onaylanırken, girdinin büyük harflerle yazılması durumunda çıktının değişmeyeceğini belirtmeniz iyi olur. Olduğu söyleniyor, cevabı olduğu gibi (düzenleme önerisi ile toLowerCase) geliştiricilerin niyetlerini varsayandan daha esnek / kullanışlı olduğunu hissediyorum . Bu yöntem ayrıca PHP ( ucwords) ve Golang ( strings.Title) gibi diğer dillerin benzer yerleşik yöntemlerinin işlevselliğini de yansıtır . .NET ( TextInfo.ToTitleCase) ilginç karışık durumda çalışır, ama aynı zamanda tamamen büyük harfli dizeleri değişmeden bırakır.
Tom Kay

20

Regex kullanmadan sadece referans için:

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


Normal ifade içermeyen çözüm için teşekkürler!
lucifer63

20

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

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


Sadece bir soru, () yapısı seçeneklerden herhangi birindeki bir eşleşmeyi belirtmektir: yani, (a | b) a veya b ile eşleşir. İnşaat (.) Ne yapar?
Michael Blackburn

Aynı soruyu cevaplayan herkes için, değiştirme bölümünde kullanılan bir "damla" tanımlar. Lekeler sırayla numaralandırılır, ilk () 1 $ 'a, ikincisi 2 $' a konur. Bu siteyi faydalı buldum: javascript.info/tutorial/regular-expressions-methods
Michael Blackburn

Yukarıdakilerin çalışmasını sağlayamıyorum, ama normal ifade sihirbazından çok uzakım. 'string'.replace(/^(.)(.*)/,function(s,p1,p2){return p1.toUpperCase()+p2;}) Tekrar kullanıyorum , bu sadece bir dizenin ilk harfini büyük yapmak için çalışıyor, ancak ihtiyacınız olan şey olursa inşaatım işe yarıyor.
Michael Blackburn

1
Bazı nedenlerden dolayı FF35 boğuluyor gibi '$1'.toUpperCase()görünüyor, büyük harf değerin atandığı zaman yapılmadı. Fonksiyonu kullanarak çalıştı'string'.replace(/^(.){1}/,function(match) { return match.toUpperCase(); })
MrYellow

Herkese selam, cevap sabit! Başlangıçta yayınladığım zamana kadar çalıştığından eminim. Neyse giriş için teşekkürler!
simo

17

Hemen toLowerCasedizeyi ve daha sonra toUpperCaseher kelimenin ilk harfini kullanabilirsiniz. Çok basit bir 1 astar olur:

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

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


Bu çözümü seviyorum; güzel ve basit. Gerçi cevabınıza biraz CoffeeScript kaymış gibi görünüyor ( s => s.toUpperCase()). Benim varyant yaptığınız şeyi yapmak, ancak String nesnesini genişletmektir (olduğu gibi tartışmalı):Object.defineProperty(String.prototype, '_toProperCase', {value:function() {return this.toLowerCase().replace(/\b(\w)/g, function(t) {return t.toUpperCase()})}})
Waz

1
@Waz, fikirler için teşekkürler! Sadece açıklığa kavuşturmak istedim =>, bu bir yerel ok işlevi (ES6), bağlantı, üzerinde bir destek tablosu sağlayan Mozillla Dokümanlarına atlar.
KevBot

16

Bu doldurucu kelimeler hakkında endişelenmeniz durumunda, işleve her zaman büyük harf kullanmamanızı söyleyebilirsiniz.

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

Umarım bu size yardımcı olur.

Düzenle

Eğer önde gelen tutkal kelimeleri ele almak istiyorsanız, bu w / bir değişkenini takip edebilirsiniz:

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
Bir dizeyi bir diziye patlatabilirsiniz. Portekizce, İspanyolca, İtalyanca ve Fransızca edatlarımız olabilirdi:glue ='de|da|del|dos|do|das|des|la|della|delli'.split('|');
Junior Mayhé

Bu, ilk kelimenin büyük harf kullanımını sağlamaz; yani and another thingolur and Another Thing. Her zaman ilk kelimeyi büyük harfle yazmak için zarif bir yola ihtiyacınız var.
Brad Koch

@BradKoch - boşluklarla doldurun, böylece arama kelimesi olarak 've', 'de' vb. Kullanırsınız, daha sonra 'And Another And Another' yerine 'And Another and Another' ifadesinin yerini alır.
Yimin Rong

iyi hariç 've' H'Dy veya Number-One gibi metinleri de büyük harfle yazıyor
luky

Üçlü bir operatör kullanmak yerine sadece bir yedek kullanabilirsiniz: glue = glue || ['of', 'için', 've', 'a'];
19:42, tm2josep

14

Yukarıdaki çözümlerde kullanılan normal ifade sizi karıştırıyorsa, şu kodu deneyin:

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

Sevdim! dizilere dönüşüm yok.
neelmeg

1
uhhh ... split gelmez çünkü bir diziye dönüştürmek, sen de açıkçası görmüyorum mapEğer kullanım gerekmez araçlar []gösterimde
MalcolmOcean

2
Bu a8m'nin 2 yıl önceki cevabı ile aynı .
Michael - Clay Shirky

1
Tek karakterlik girişler için kesmeler.
Madbreaks

1
@AlexChaffee düzeltme geçmişini kontrol edin. a8m orijinal yanıtta ok işlevi kullanmadı.
Teşekkürler

9

"McDonald" veya "MacDonald" veya "O'Toole" veya "D'Orazio" gibi soyadlarını (başlık durumu değil) işleyebilen bu işlevi yaptım. Ancak Almanca ya da Hollandaca isimleri genellikle küçük harf olan "van" ya da "von" ile işlemez ... "de" nin "Robert de Niro" gibi genellikle küçük harf olduğuna inanıyorum. Bunlar hala ele alınmalıdır.

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
İsim farkındalığı için +1. Yine de, "macy" doğru işlemez.
brianary

Büyük ve küçük harfleri doğru duruma dönüştüren ve "ABD Virjin Adaları" gibi adının baş harflerini fark eden tek işlev buydu.
Rodrigo Polo

Sen etrafında alabilirsiniz macyorada bir negatif ileri yönlü koyarak sorunu böylece \b((m)(a?c))?(\w)olur\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 : "");
    }
)

Çalışıyor gibi görünüyor ... Yukarıdaki ile test, "çabuk kahverengi, tilki? / Atlar / ^ üzerinde ^ tembel! Köpek ..." ve "C: / program dosyaları / bazı satıcı / onların 2. uygulama / a file1.txt".

2 yerine 2Nd istiyorsanız, /([a-z])(\w*)/g .

İlk form aşağıdaki gibi basitleştirilebilir:

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

7

Bunu dene

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

Misal

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

7

Kodunuzda üçüncü taraf kitaplıkları kullanabiliyorsanız, lodash'ın bizim için bir yardımcı işlevi vardır.

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

Bunu en kısa yoldan deneyin:

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

Başka

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

Sadece bir s.slice(0, 1).toUpperCase()mektup yukarı, muhtemelen hala ilk harfi istiyorsan olmalı .
WindsofTime

@jssridhar ES6'daki kodu da düzeltmelisiniz.
caiosm1005

1
strTek bir karakter ise tatili
Madbreaks

@jssridhar bizim için daha iyi olabilir .charAt(0).toUpperCase().
roydukkey

2
a8m cevabının kopyası
Teşekkürler

6

Bu cevapların çoğu, sınır metakarakter (\ b) kelimesini kullanma olasılığını göz ardı etmektedir. Greg Dean'in bu cevabı kullanmasının daha kısa bir versiyonu:

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

Jim-Bob gibi tireli isimler için de çalışır.


2
Zarif bir kısmi çözümdür, ancak vurgu veya büyük harf dizeleriyle çalışmaz. "Sofía Vergara" => "SofíA Vergara" veya "Sofía VERGARA" => "SofíA VERGARA" alırım. İkinci durum .replace (...) 'den önce Apply .toLowerCase () işleviyle çözülebilir. İlk vakanın doğru bir düzenli ifade bulması gerekir.
Asereware

2
Hmm, regex uygulamasında bir hata gibi görünüyor, aksanlı karakter kelime karakterleri olacağını düşünürdüm (olsa da, haklısın, olduğu gibi bu durumlarda işe yaramaz).
lewax00

\wyalnızca [A-Za-z0-9_]harfleri içerir, tüm harfleri içermez. Bunun için Unicode kategorisini kullanmanız gerekir \p{L}. Şunlar gerekir /udeğiştirici (bkz burada ) ve ilgili farklı çözümler \bsadece arasında çalışır, \Wve \w(bkz burada )
cmbuckley

6

Bence en basiti css kullanıyor.

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

Kodu güncelledim ve test ettim. Şimdi çalışmalı.
wondim

CSS'yi yalnızca JS'nin kullanıldığı ortamların bir kısmında kullanabilirsiniz, bu nedenle bu çözüm geçerli değildir. Ayrıca satır içi stiller her ne pahasına olursa olsun kaçınılmalıdır.
Madbreaks

5

/\S+/gAksanları desteklemek için kullanın :

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

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


5

Burada listelenentoTitleCase gramer kurallarını dikkate alan sağlam bir işleve ihtiyaç duyduğum için kendi cevabımı eklemek istedim (Google tarafından önerilen makale). Giriş dizesinin uzunluğuna bağlı çeşitli kurallar vardır. Fonksiyon + birim testleri aşağıdadır.

İşlev ayrıca boşlukları birleştirir ve özel karakterleri kaldırır (gereksinimleriniz için normal ifadeyi değiştirin)

toTitleCase İşlevi

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

Doğruluğu Sağlamak İçin Birim Testleri

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

Sağlanan dizelerden biraz özel karakter kaldırdığımı lütfen unutmayın. Projenizin gereksinimlerini karşılamak için normal ifadeyi değiştirmeniz gerekir.


Başlık çözümüne gerçekten önem verdiği için bu çözümü tercih ediyorum. "Rüzgar Gibi Geçti" değil "Rüzgar Gibi Geçti"
russellmania

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

1
Örnek için çalışır ve o'henrygarip şeyler yapar horse's mouth.
Michael - Clay Shirky

"john f. kennEdy".toLowerCase().replace(/\b\S/g, t => t.toUpperCase())daha iyi 🤔
w3debugger

@ Proximo'nun cevabını düzenlemek istemiyordu: \bve \S, “kelime sınırı” ve “tek, boşluk olmayan karakteri gösteren özel karakter sınıflarıdır . Bu nedenle, normal ifade, bir kelime sınırını izleyen her karakterle eşleşir ve verilen ok işlevini uygulayarak bu karakteri büyük harf yapar.
Jens

4

"Lewax00" çözümünü alarak, boşlukla başlayarak "w" ye ya da kelime başlatan "w" ye zorlayan, ancak fazladan ara boşlukları kaldıramayan bu basit çözümü yarattım.

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

Sonuç "Sofía Vergara" dır.


4

Burada aksanlı karakterlerle ilgilenen (fransızca için önemli!) İşlevim ve istisnaların azaltılmasını açıp kapatabilen işlevim. Umarım yardımcı olur.

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

Burada ofiste bir tartışma yapıyoruz ve insanların isimleri istediğiniz şekilde girme şeklini otomatik olarak düzeltmeye çalışmanın olası sorunlarla dolu olduğunu düşünüyoruz.

Farklı otomatik büyük harf türlerinin dağıldığı ve bunların yalnızca İngilizce isimler için olduğu, her dilin kendine özgü karmaşıklıkları olan birkaç durumla karşılaştık.

Her ismin ilk harfini büyük harfe çeviren sorunlar:

• IBM gibi kısaltmaların girilmesine izin verilmez, IBM'e dönüştürülür.

• McDonald adı yanlış olan Mcdonald'a dönüşür, aynı şey MacDonald için de geçerlidir.

• Marie-Tonks gibi çift namlulu isimler Marie-tonks'a dönüşecekti.

• O'Connor gibi isimler O'connor'a dönüşecekti.

Bunların çoğu için bununla başa çıkmak için özel kurallar yazabilirsiniz, ancak bunun daha önce olduğu gibi Acronyms ile ilgili sorunları vardır ve yeni bir sorun elde edersiniz:

• MacDonald gibi Mac ile adları düzeltmek için bir kural eklemek, Macy gibi kesme adlarını MacY'ye dönüştürür.

Hiç yanlış gelmediğimiz tek çözüm, DBS'nin de kullandığı kaba kuvvet yöntemi olan her harfi büyük harfle yazmaktır.

İşlemi otomatikleştirmek istiyorsanız, her isim ve kelimenin bir sözlüğü ve nasıl kapitleştirilmesi gerekmeksizin yapmak imkansız kadar iyidir, Her şeyi kapsayan bir kuralınız yoksa, onu kullanmayın kullanıcılarınızı rahatsız edecek ve isimlerini doğru girmek isteyen kişilere başka bir yere gitmelerini isteyecektir.


4

css (ve dönüştürmek istediğiniz metin büyük harf içeriyorsa) javascript kullanan başka bir çözüm:

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

Düzenli ifadelerden korkanlarımız için (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

Tek satırlık çözümüm:

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

Ardından, yöntemi capitalizeWords()herhangi bir dizede çağırabilirsiniz . Örneğin:

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

>>> This Actually Works

Diğer çözümüm:

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

Ardından, yöntemi capitalizeWords()herhangi bir dizede çağırabilirsiniz . Örneğin:

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

>>> This One Works Too

Greg Dean yanıtına dayalı alternatif çözüm:

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

Ardından, yöntemi capitalizeWords()herhangi bir dizede çağırabilirsiniz . Örneğin:

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

>>> Yes And No

3

Dinlenme parametresinin kullanımından hiç kimsenin bahsetmediğini görmek şaşırdı. İşte ES6 Rest parametrelerini kullanan basit bir astar.

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


2

Bu, FreeCodeCamp'ın Bonfire "Title Case" çözümüne dayanıyor , bu da önce verilen dizeyi tüm küçük harflere dönüştürmenizi ve daha sonra bir boşlukta ilerleyen her karakteri büyük harfe dönüştürmenizi gerektiriyor.

Normal ifade kullanmadan:

function titleCase(str) {
 return str.toLowerCase().split(' ').map(function(val) { return val.replace(val[0], val[0].toUpperCase()); }).join(' ');
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.