Bagaimana cara mengubah string menjadi Title Case dengan Python?

97

Contoh:

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

Apakah ada pustaka atau cara standar untuk melakukan tugas ini?

pelamun
sumber
16
Itu bukan "CamelCase", itu "Capitalize"; yang mana yang kamu mau
Andrew Marshall
13
CamelCase seperti ini.
Jonathan M
5
Contoh Anda menggunakan PascalCase.
David Betz

Jawaban:

219

Mengapa tidak menggunakan titleRight from the docs:

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

Jika Anda benar-benar menginginkan PascalCase, Anda dapat menggunakan ini:

>>> ''.join(x for x in 'make IT pascal CaSe'.title() if not x.isspace())
'MakeItPascalCase'
Facundo Casco
sumber
5
Saya pikir 'r' dalam "They" harus menggunakan huruf kecil. Dan huruf 'dalam "Bill" pasti menggunakan huruf kecil.
Daniel Fischer
3
@Daniel - Masalah itu dicatat dalam dokumen untuk title: "Algoritme menggunakan definisi sederhana bahasa-independen dari sebuah kata sebagai kelompok huruf yang berurutan. Definisi tersebut bekerja dalam banyak konteks tetapi itu berarti bahwa apostrof dalam kontraksi dan kepemilikan membentuk batas kata, yang mungkin bukan hasil yang diinginkan ". Salah satu solusi yang mungkin adalah menggunakan jawaban Laurence dengan ekspresi reguler r"['\w]+"sehingga apostrof tidak akan mengakhiri kecocokan (tanda baca tambahan dapat ditambahkan sesuai kebutuhan).
Andrew Clark
18
Sebagai catatan, cara yang lebih rapi untuk melakukan contoh CamelCase terakhir adalah sebagai 'make IT camel CaSe'.title().replace(' ', '').
Henry Gomersall
15
Jika ada orang lain yang merasa seperti sedang minum pil gila - ini adalah PascalCase, bukan camelCase.
Rob
4
Kode bagus tapi camelCase tidak dimulai dengan MODAL. Coba ini: def toCamel(s): ret = ''.join(x for x in s.title() if not x.isspace()) return ret[0].lower() + ret[1:] Penggunaan:toCamel("WRITE this in camelcase") 'writeThisInCamelcase'
Ron Kalian
22

Yang ini akan selalu dimulai dengan huruf kecil, dan juga menghapus karakter non alfanumerik:

def camelCase(st):
    output = ''.join(x for x in st.title() if x.isalnum())
    return output[0].lower() + output[1:]
Ivan Chaer
sumber
8
def capitalizeWords(s):
  return re.sub(r'\w+', lambda m:m.group(0).capitalize(), s)

re.subdapat mengambil fungsi untuk "pengganti" (bukan hanya string, yang penggunaan kebanyakan orang tampaknya akrab). Fungsi repl ini akan dipanggil dengan re.Matchobjek untuk setiap kecocokan pola, dan hasilnya (yang seharusnya berupa string) akan digunakan sebagai pengganti kecocokan tersebut.

Versi yang lebih panjang dari hal yang sama:

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

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

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

Ini mengkompilasi pola sebelumnya (umumnya dianggap sebagai bentuk yang baik) dan menggunakan fungsi bernama alih-alih lambda.

Laurence Gonsalves
sumber
yang ini cukup rapi, saya mencoba memahami fungsi lambda, terima kasih telah membantu
lamunan
1
@JohnMachin Saya hanya bertanya karena saya pikir menambahkan beberapa penjelasan akan membuat jawaban Anda lebih lengkap dan lebih baik.
NN
@Laurence Gonsalves apa yang lambda lakukan di sini?
Sion
apa yang lambda lakukan disini? dari apa yang bisa saya pecahkan dan dari penjelasan Anda. inilah yang saya mengerti. ketika Anda menggunakan fungsi di re.sub masing match- masing akan diteruskan ke fungsi? dan karena matchesdalam ekspresi reguler memiliki grup. itu sebabnya baris ini ada lambda m:m.group(0).capitalize()?
Sion
@Ionya ya. Ketika re.subdiberikan callable (misalnya: sebuah fungsi) sebagai "pengganti", ia meneruskan objek yang cocok ke callable tersebut, dan mengharapkan untuk mendapatkan kembali string yang sebenarnya digunakan sebagai pengganti. Jika Anda merasa lambda membingungkan, "versi yang lebih panjang" melakukan hal yang persis sama dengan cara yang lebih bertele-tele.
Laurence Gonsalves
5

Mengapa tidak menulisnya? Sesuatu seperti ini dapat memenuhi kebutuhan Anda:

def FixCase(st):
    return ' '.join(''.join([w[0].upper(), w[1:].lower()]) for w in st.split())
banyak antarmuka
sumber
terima kasih, itu sangat membantu. Saya buruk, saya tidak berpikir untuk menulis satu di tempat pertama
pelamun
5

Catatan: Mengapa saya memberikan jawaban lain? Jawaban ini didasarkan pada judul pertanyaan dan pengertian bahwa camelcase diartikan sebagai: rangkaian kata yang telah digabung (tanpa spasi!) Sedemikian rupa sehingga setiap kata asli dimulai dengan huruf kapital (sisanya huruf kecil) kecuali kata pertama dari rangkaian (yang sepenuhnya huruf kecil). Juga diasumsikan bahwa "semua string" mengacu pada himpunan karakter ASCII; unicode tidak akan berfungsi dengan solusi ini).

sederhana

Diberikan definisi di atas, fungsi ini

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

, saat dipanggil, akan menghasilkan cara ini

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

kurang sederhana

Perhatikan bahwa itu gagal ketika disajikan dengan unta yang sudah bersarung tali!

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

bahkan tidak sesederhana itu

Perhatikan bahwa ini gagal dengan banyak string unicode

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

Saya tidak memiliki solusi untuk kasus ini (atau kasus lain yang dapat diperkenalkan dengan beberapa kreativitas). Jadi, seperti dalam semua hal yang berkaitan dengan string, tutupi casing edge Anda sendiri dan semoga sukses dengan unicode!

Marc
sumber
Bagaimana Anda bisa menentukan bahwa string adalah kasus Camel tanpa mengetahui arti kalimat? Dalam contoh "kurang sederhana" Anda, "sanfRancisco" adalah huruf besar / kecil Camel dan juga "itSnotcaMelcAse".
Patrice Bernassola
Saya menduga masukan Anda mengandung apostraf atau tanda baca lainnya? Saya harus mencatat masukan gagal lainnya. Pasti tangkapan yang bagus. Apa masukan yang Anda berikan?
Marc
1
Maksud saya dari urutan karakter tanpa spasi harus dianggap sebagai 1 kata. Anda tidak dapat mengekstrak karya darinya tanpa mengetahui arti kalimatnya. Letakkan "sanfRancisco" atau "itSnotcaMelcAse" sebagai masukan dari camello () dan Anda akan melihat bahwa keluarannya akan sama.
Patrice Bernassola
Oh begitu - ya, saya pikir Anda benar. Saya overfit solusinya. Saya akan memperbaruinya.
Marc
4

Perpustakaan potensial: https://pypi.org/project/stringcase/

Contoh:

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

Meskipun dipertanyakan apakah itu akan meninggalkan spasi. (Contoh menunjukkan itu menghapus ruang, tetapi ada masalah pelacak bug yang mencatat bahwa itu meninggalkannya).

Lol
sumber
Ya. Sedang mencari paket. Paket ini memiliki snakecase dan fungsi konversi lainnya juga.
s2t2
1

cukup gunakan .title (), dan itu akan mengubah huruf pertama dari setiap kata menjadi kapital, istirahat kecil:

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

Saya ingin menambahkan sedikit kontribusi saya untuk posting ini:

def to_camelcase(str):
  return ' '.join([t.title() for t in str.split()])
Evhz
sumber
Sebenarnya, str.title () sama dan Anda menghemat biaya komputasi.
Auros132
1
def camelCase(st):
    s = st.title()
    d = "".join(s.split())
    d = d.replace(d[0],d[0].lower())
    return d
Aishwarya Skandamani
sumber