Myślę, że „r” w słowie „Oni” powinno być małe. A „s” w „Bill's” zdecydowanie musi być małymi literami.
Daniel Fischer,
3
@Daniel - Ta kwestia jest odnotowana w dokumentach dla title: „Algorytm używa prostej, niezależnej od języka definicji słowa jako grup następujących po sobie liter. Definicja działa w wielu kontekstach, ale oznacza, że apostrofy w skrótach i dzierżawcze tworzą granice słów, co może nie być pożądanym rezultatem ”. Jednym z możliwych rozwiązań byłoby użycie odpowiedzi Laurence'a z wyrażeniem regularnym, r"['\w]+"aby apostrofy nie kończyły dopasowania (w razie potrzeby można było dodać dodatkowe znaki interpunkcyjne).
Andrew Clark
18
Dla przypomnienia, bardziej schludnym sposobem wykonania ostatniego przykładu CamelCase jest użycie pliku 'make IT camel CaSe'.title().replace(' ', '').
Henry Gomersall,
15
Jeśli ktoś czuje, że bierze szalone pigułki - to PascalCase, a nie camelCase.
Rob
4
Niezły kod, ale camelCase nie zaczyna się od WIELKIEGO. Spróbuj tego: def toCamel(s): ret = ''.join(x for x in s.title() if not x.isspace()) return ret[0].lower() + ret[1:] Sposób użycia:toCamel("WRITE this in camelcase") 'writeThisInCamelcase'
Ron Kalian
22
Ten zawsze zaczynałby się od małych liter, a także usuwał znaki inne niż alfanumeryczne:
defcamelCase(st):
output = ''.join(x for x in st.title() if x.isalnum())
return output[0].lower() + output[1:]
re.submoże przyjąć funkcję do „zamiany” (zamiast zwykłego ciągu znaków, co wydaje się być znane większości ludzi). Ta funkcja repl zostanie wywołana z re.Matchobiektem dla każdego dopasowania wzorca, a wynik (który powinien być łańcuchem znaków) zostanie użyty jako zamiennik dla tego dopasowania.
ten jest całkiem fajny, próbuję ogarnąć funkcje lambda, dziękuję za pomoc
daydreamer
1
@JohnMachin Właśnie zapytałem, ponieważ pomyślałem, że dodanie wyjaśnienia sprawi, że Twoja odpowiedź będzie pełniejsza i lepsza.
NN
@Laurence Gonsalves, co tu robi lambda?
Zion
co tu robi lambda? z tego, co mogę rozszyfrować i od Ciebie wyjaśnienia. to właśnie zrozumiałem. kiedy używasz funkcji w re.sub, każda z nich matchzostanie przekazana do funkcji? a ponieważ matchesw wyrażeniach regularnych mają grupy. dlatego istnieje ta linia lambda m:m.group(0).capitalize()?
Zion
@Zion yes. Kiedy re.subjako „zamiennik” otrzyma wywoływalną funkcję (np. Funkcję), przekazuje obiekt dopasowania do tego wywoływalnego i oczekuje, że odzyska łańcuch, którego faktycznie używa jako zamiennika. Jeśli uznasz lambdy za mylące, „dłuższa wersja” robi dokładnie to samo, w bardziej szczegółowy sposób.
Laurence Gonsalves
5
Dlaczego by nie napisać? Coś takiego może spełnić Twoje wymagania:
defFixCase(st):return' '.join(''.join([w[0].upper(), w[1:].lower()]) for w in st.split())
dzięki, to pomogło całkowicie. Mój zły, nie pomyślałem, żebym napisał jeden na pierwszym miejscu
marzyciel
5
Uwaga: dlaczego udzielam jeszcze innej odpowiedzi? Ta odpowiedź opiera się na tytule pytania i założeniu, że wielkie litery definiuje się jako: serię słów, które zostały połączone (bez spacji!) W taki sposób, że każde z oryginalnych słów zaczyna się wielką literą (reszta jest małą) z wyjątkiem pierwszego słowa z serii (które jest całkowicie małe). Zakłada się również, że „wszystkie łańcuchy” odnoszą się do zestawu znaków ASCII; Unicode nie będzie działać z tym rozwiązaniem).
prosty
Biorąc pod uwagę powyższą definicję, ta funkcja
import re
word_regex_pattern = re.compile("[^A-Za-z]+")
defcamel(chars):
words = word_regex_pattern.split(chars)
return"".join(w.lower() if i is0else w.title() for i, w in enumerate(words))
, gdy zostanie wywołany, spowoduje to w ten sposób
Nie mam rozwiązania dla tych przypadków (lub innych, które można by wprowadzić przy odrobinie kreatywności). Tak więc, podobnie jak we wszystkich rzeczach, które mają związek ze strunami, zakryj własne skrajne przypadki i powodzenia w unicode!
Jak możesz ustalić, że ciąg znaków to przypadek Camel, nie znając znaczenia zdania? W twoim „mniej prostym” przykładzie „sanfRancisco” to zarówno obudowa Camel, jak i „itSnotcaMelcAse”.
Patrice Bernassola
Zgaduję, że Twój wpis zawierał apostyk lub inną interpunkcję? Powinienem zwrócić uwagę na inne błędne dane wejściowe. Zdecydowanie dobry połów. Jaki był Twój wkład?
Marc,
1
Chodzi mi o to, że ciąg znaków bez spacji należy traktować jako 1 słowo. Nie możesz wydobyć z niego pracy bez znajomości znaczenia zdania. Umieść "sanfRancisco" lub "itSnotcaMelcAse" jako wejście funkcji camello (), a zobaczysz, że wynik będzie taki sam.
Patrice Bernassola
Och, rozumiem - tak, myślę, że masz rację. Przekonałem rozwiązanie. Zaktualizuję to.
Chociaż wątpliwe jest, czy pozostawi spacje. (Przykłady pokazują, że usuwa spację, ale istnieje problem z trackerem błędów, który zauważa, że pozostawia je).
Odpowiedzi:
Dlaczego nie skorzystać bezpośrednio
title
z dokumentacji:>>> "they're bill's friends from the UK".title() "They'Re Bill'S Friends From The Uk"
Jeśli naprawdę chciałeś PascalCase, możesz użyć tego:
>>> ''.join(x for x in 'make IT pascal CaSe'.title() if not x.isspace()) 'MakeItPascalCase'
źródło
title
: „Algorytm używa prostej, niezależnej od języka definicji słowa jako grup następujących po sobie liter. Definicja działa w wielu kontekstach, ale oznacza, że apostrofy w skrótach i dzierżawcze tworzą granice słów, co może nie być pożądanym rezultatem ”. Jednym z możliwych rozwiązań byłoby użycie odpowiedzi Laurence'a z wyrażeniem regularnym,r"['\w]+"
aby apostrofy nie kończyły dopasowania (w razie potrzeby można było dodać dodatkowe znaki interpunkcyjne).'make IT camel CaSe'.title().replace(' ', '')
.def toCamel(s): ret = ''.join(x for x in s.title() if not x.isspace()) return ret[0].lower() + ret[1:]
Sposób użycia:toCamel("WRITE this in camelcase") 'writeThisInCamelcase'
Ten zawsze zaczynałby się od małych liter, a także usuwał znaki inne niż alfanumeryczne:
def camelCase(st): output = ''.join(x for x in st.title() if x.isalnum()) return output[0].lower() + output[1:]
źródło
def capitalizeWords(s): return re.sub(r'\w+', lambda m:m.group(0).capitalize(), s)
re.sub
może przyjąć funkcję do „zamiany” (zamiast zwykłego ciągu znaków, co wydaje się być znane większości ludzi). Ta funkcja repl zostanie wywołana zre.Match
obiektem dla każdego dopasowania wzorca, a wynik (który powinien być łańcuchem znaków) zostanie użyty jako zamiennik dla tego dopasowania.Dłuższa wersja tego samego:
WORD_RE = re.compile(r'\w+') def capitalizeMatch(m): return m.group(0).capitalize() def capitalizeWords(s): return WORD_RE.sub(capitalizeMatch, s)
To wstępnie kompiluje wzorzec (ogólnie uważany za dobrą formę) i używa nazwanej funkcji zamiast lambda.
źródło
match
zostanie przekazana do funkcji? a ponieważmatches
w wyrażeniach regularnych mają grupy. dlatego istnieje ta linialambda m:m.group(0).capitalize()
?re.sub
jako „zamiennik” otrzyma wywoływalną funkcję (np. Funkcję), przekazuje obiekt dopasowania do tego wywoływalnego i oczekuje, że odzyska łańcuch, którego faktycznie używa jako zamiennika. Jeśli uznasz lambdy za mylące, „dłuższa wersja” robi dokładnie to samo, w bardziej szczegółowy sposób.Dlaczego by nie napisać? Coś takiego może spełnić Twoje wymagania:
def FixCase(st): return ' '.join(''.join([w[0].upper(), w[1:].lower()]) for w in st.split())
źródło
Uwaga: dlaczego udzielam jeszcze innej odpowiedzi? Ta odpowiedź opiera się na tytule pytania i założeniu, że wielkie litery definiuje się jako: serię słów, które zostały połączone (bez spacji!) W taki sposób, że każde z oryginalnych słów zaczyna się wielką literą (reszta jest małą) z wyjątkiem pierwszego słowa z serii (które jest całkowicie małe). Zakłada się również, że „wszystkie łańcuchy” odnoszą się do zestawu znaków ASCII; Unicode nie będzie działać z tym rozwiązaniem).
prosty
Biorąc pod uwagę powyższą definicję, ta funkcja
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))
, gdy zostanie wywołany, spowoduje to w ten sposób
camel("San Francisco") # sanFrancisco camel("SAN-FRANCISCO") # sanFrancisco camel("san_francisco") # sanFrancisco
mniej proste
Zwróć uwagę, że nie udaje się, gdy jest przedstawiony ze sznurkiem w wielbłądzie!
camel("sanFrancisco") # sanfrancisco <-- noted limitation
jeszcze mniej proste
Zauważ, że kończy się niepowodzeniem z wieloma ciągami znaków Unicode
camel("México City") # mXicoCity <-- can't handle unicode
Nie mam rozwiązania dla tych przypadków (lub innych, które można by wprowadzić przy odrobinie kreatywności). Tak więc, podobnie jak we wszystkich rzeczach, które mają związek ze strunami, zakryj własne skrajne przypadki i powodzenia w unicode!
źródło
Potencjalna biblioteka: https://pypi.org/project/stringcase/
Przykład:
import stringcase stringcase.camelcase('foo_bar_baz') # => "fooBarBaz"
Chociaż wątpliwe jest, czy pozostawi spacje. (Przykłady pokazują, że usuwa spację, ale istnieje problem z trackerem błędów, który zauważa, że pozostawia je).
źródło
po prostu użyj .title (), a skonwertuje pierwszą literę każdego słowa z wielkiej litery, resztę na małe:
>>> a='mohs shahid ss' >>> a.title() 'Mohs Shahid Ss' >>> a='TRUE' >>> b=a.title() >>> b 'True' >>> eval(b) True
źródło
Chciałbym dodać swój mały wkład do tego postu:
def to_camelcase(str): return ' '.join([t.title() for t in str.split()])
źródło
def camelCase(st): s = st.title() d = "".join(s.split()) d = d.replace(d[0],d[0].lower()) return d
źródło