Python'da dizeyi Title Case'e nasıl dönüştürebilirim?


97

Misal:

HILO -> Hilo
new york -> New York
SAN FRANCISCO -> San Francisco

Bu görevi gerçekleştirmenin bir kütüphanesi veya standart bir yolu var mı?


16
Bu "CamelCase" değil, bu "Capitalize"; hangisini istersin?
Andrew Marshall

13
camelCase böyle.
Jonathan M

5
Örnekleriniz PascalCase kullanıyor.
David Betz

Yanıtlar:


219

Neden titlebelgelerden Sağ'ı kullanmıyorsunuz?

>>> "they're bill's friends from the UK".title()
"They'Re Bill'S Friends From The Uk"

PascalCase'i gerçekten istiyorsanız, bunu kullanabilirsiniz:

>>> ''.join(x for x in 'make IT pascal CaSe'.title() if not x.isspace())
'MakeItPascalCase'

5
Bence "Onlar" daki "r" küçük harf olmalıdır. Ve "Bill'in" içindeki 's' kesinlikle küçük harf olmalıdır.
Daniel Fischer

3
@Daniel - Bu sorun aşağıdaki belgelerde belirtilmiştir title: "Algoritma, bir kelimenin ardışık harf grupları olarak dilden bağımsız basit bir tanımını kullanır. Tanım birçok bağlamda işe yarar, ancak kısaltmalardaki ve iyeliklerdeki kesme işaretlerinin kelime sınırlarını oluşturduğu anlamına gelir, bu istenen sonuç olmayabilir ". Olası bir çözüm, Laurence'in yanıtını normal ifadeyle kullanmaktır, r"['\w]+"böylece kesme işaretleri eşleşmeyi sonlandırmaz (gerektiğinde ek noktalama eklenebilir).
Andrew Clark

18
Kayıt için, son CamelCase örneğini yapmanın daha düzgün bir yolu 'make IT camel CaSe'.title().replace(' ', '').
Henry Gomersall

15
Başka biri çılgın haplar kullanıyormuş gibi hissediyorsa - bu PascalCase, camelCase değil.
Rob

4
Güzel kod ama camelCase CAPITAL ile başlamıyor. def toCamel(s): ret = ''.join(x for x in s.title() if not x.isspace()) return ret[0].lower() + ret[1:] toCamel("WRITE this in camelcase") 'writeThisInCamelcase'
Şunu

22

Bu her zaman küçük harfle başlar ve ayrıca alfanümerik olmayan karakterleri çıkarır:

def camelCase(st):
    output = ''.join(x for x in st.title() if x.isalnum())
    return output[0].lower() + output[1:]

8
def capitalizeWords(s):
  return re.sub(r'\w+', lambda m:m.group(0).capitalize(), s)

re.sub"değiştirme" için bir işlev alabilir (çoğu insanın aşina olduğu bir kullanım olan bir dizeden ziyade). Bu repl işlevi re.Match, modelin her eşleşmesi için bir nesneyle çağrılacak ve sonuç (bir dizge olmalıdır) bu eşleşmenin yerine geçecek şekilde kullanılacaktır.

Aynı şeyin daha uzun bir versiyonu:

WORD_RE = re.compile(r'\w+')

def capitalizeMatch(m):
  return m.group(0).capitalize()

def capitalizeWords(s):
  return WORD_RE.sub(capitalizeMatch, s)

Bu, kalıbı önceden derler (genellikle iyi bir biçim olarak kabul edilir) ve lambda yerine adlandırılmış bir işlevi kullanır.


bu oldukça düzgün, lambda işlevlerini anlamaya çalışıyorum, yardım ettiğiniz için teşekkürler
daydreamer

1
@JohnMachin Sadece sordum çünkü bazı açıklamalar eklemenin cevabınızı daha eksiksiz ve daha iyi hale getireceğini düşündüm.
NN

@Laurence Gonsalves lambda burada ne yapıyor?
Zion

lambda burada ne yapıyor? Neyi deşifre edebilirim ve sizden açıklama. anladığım buydu. re.sub'da bir işlev kullandığınızda, her biri matchişleve geçirilecek? ve çünkü matchesnormal ifadelerde gruplar var. bu yüzden bu hat var lambda m:m.group(0).capitalize()?
Zion

@Zion evet. Ne zaman re.subbir çağrılabilir verilir: "yerine" olarak (örneğin bir işlevi), o kadar çağrılabilir için maç nesneyi iletir ve beklediği aslında yedek olarak kullandığı bir dize geri almak için. Lambdaları kafa karıştırıcı bulursanız, "daha uzun sürüm" tam olarak aynı şeyi daha ayrıntılı bir şekilde yapar.
Laurence Gonsalves

5

Neden bir tane yazmıyorsun? Bunun gibi bir şey gereksinimlerinizi karşılayabilir:

def FixCase(st):
    return ' '.join(''.join([w[0].upper(), w[1:].lower()]) for w in st.split())

teşekkürler, bu tamamen yardımcı oldu. Benim hatam, ilk etapta bir tane yazmayı düşünmedim
daydreamer

5

Not: Neden başka bir cevap veriyorum? Bu cevap, sorunun başlığına ve deve harfinin şu şekilde tanımlandığı fikrine dayanmaktadır: orijinal kelimelerin her biri bir büyük harfle başlayacak şekilde (geri kalanı küçük harf olmak üzere) birleştirilmiş (boşluksuz!) Bir dizi kelime Serinin ilk kelimesi hariç (tamamen küçük harf). Ayrıca "tüm dizelerin" ASCII karakter kümesini ifade ettiği varsayılır; unicode bu çözümle çalışmaz).

basit

Yukarıdaki tanım göz önüne alındığında, bu işlev

import re
word_regex_pattern = re.compile("[^A-Za-z]+")

def camel(chars):
  words = word_regex_pattern.split(chars)
  return "".join(w.lower() if i is 0 else w.title() for i, w in enumerate(words))

, çağrıldığında bu şekilde sonuçlanır

camel("San Francisco")  # sanFrancisco
camel("SAN-FRANCISCO")  # sanFrancisco
camel("san_francisco")  # sanFrancisco

daha az basit

Zaten deve kasalı bir ip ile sunulduğunda başarısız olduğunu unutmayın!

camel("sanFrancisco")   # sanfrancisco  <-- noted limitation

daha az basit

Birçok unicode dizesiyle başarısız olduğunu unutmayın.

camel("México City")    # mXicoCity     <-- can't handle unicode

Bu vakalar için (veya biraz yaratıcılıkla ortaya çıkabilecek diğer vakalar) için bir çözümüm yok. Öyleyse, dizelerle ilgili her şeyde olduğu gibi, kendi uç durumlarınızı koruyun ve unicode ile iyi şanslar!


Cümlenin anlamını bilmeden bir dizenin Camel durumu olduğunu nasıl anlarsınız? Sizin "daha az basit" örneğinizde, "sanfRancisco" Camel durumu ve "itSnotcaMelcAse" dır.
Patrice Bernassola

Girişinizde apostraflar veya başka noktalama işaretleri olduğunu tahmin ediyorum. Başarısız olan diğer girdileri not etmeliyim. Kesinlikle iyi bir av. Sağladığınız girdi neydi?
Marc

1
Demek istediğim, boşluksuz bir karakter dizisi 1 kelime olarak düşünülmelidir. Cümlenin anlamını bilmeden ondan eser çıkaramazsın. "SanfRancisco" veya "itSnotcaMelcAse" yi camello () girdisi olarak koyun ve çıktının aynı olacağını göreceksiniz.
Patrice Bernassola

Oh anlıyorum - evet, haklı olduğunu düşünüyorum. Çözüme fazla uyuyorum. Güncelleyeceğim.
Marc

4

Potansiyel kütüphane: https://pypi.org/project/stringcase/

Misal:

import stringcase
stringcase.camelcase('foo_bar_baz') # => "fooBarBaz"

İçeride boşluk bırakıp bırakmayacağı şüpheli olsa da (Örnekler boşluğu kaldırdığını gösteriyor, ancak onları içeride bıraktığını belirten bir hata izleyici sorunu var.)


Heck evet. Bir paket arıyordum. Bu pakette yılanbalığı ve diğer dönüştürme işlevleri de vardır.
s2t2

1

sadece .title () kullanın ve her kelimenin ilk harfini büyük, kalanı küçük olarak dönüştürür:

>>> a='mohs shahid ss'
>>> a.title()
'Mohs Shahid Ss'
>>> a='TRUE'
>>> b=a.title()
>>> b
'True'
>>> eval(b)
True

1

Bu gönderiye küçük katkımı eklemek istiyorum:

def to_camelcase(str):
  return ' '.join([t.title() for t in str.split()])

Aslında str.title () aynıdır ve hesaplama maliyetinden tasarruf edersiniz.
Auros132

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.