Jeśli mam ciąg, który wygląda tak:
"this_is_the_string"
Wewnątrz skryptu bash chciałbym przekonwertować go na PascalCase, tj. UpperCamelCase, aby wyglądał następująco:
"ThisIsTheString"
Przekonałem się, że konwersję do lowerCamelCase można wykonać w następujący sposób:
"this_is_the_string" | sed -r 's/([a-z]+)_([a-z])([a-z]+)/\1\U\2\L\3/'
Niestety nie znam wystarczająco dobrze wyrażeń regularnych, aby to zmienić.
shell-script
użytkownik1135541
źródło
źródło
\U\2
wstawia znaleziony tekst z drugiej grupy, przekonwertowany na WSZYSTKIE CAPS. Porównaj z\u\2
, która wstawia tekst w przypadku Zdania, z tylko pierwszym znakiem pisanym wielkimi literami. (2) Wszystkie poniższe przykłady przetłumaczą „this_is_a_string” na „ThisIsAString” - o to prosiłeś, ale jest nieco trudny do odczytania. Możesz zrewidować swoje wymagania dotyczące specjalnego przypadku pojedynczego słowa (podłańcucha). … (Ciąg dalszy)(^|_)
na(\<|_)
.Odpowiedzi:
Zamień wzór
(^|_)
na początku łańcucha lub po podkreśleniu - pierwsza grupa([a-z])
mała mała litera - druga grupaprzez
\U\2
wielkie litery drugiej grupyg
globalnie.źródło
\U
jest rozszerzeniem GNU do POSIX.sed -r 's/(^|[-_ ]+)([0-9a-z])/\U\2/g'
. Więc łańcuchy takie jak „this_is_2nd_string” też działają.Ponieważ używasz
bash
, jeśli zapisałeś ciąg w zmiennej, możesz to zrobić tylko w powłoce:${uscore//_/ }
zastępuje wszystko_
spacją,(....)
dzieli ciąg na tablicę,${arr[@]^}
konwertuje pierwszą literę każdego elementu na wielkie litery, a następnieprintf %s ..
drukuje wszystkie elementy jeden po drugim.Możesz przechowywać ciąg wielbłąda w innej zmiennej:
i użyj / użyj go później, np .:
Lub z
zsh
:(${(s:_:)uscore})
dzieli ciąg na_
tablicę, drukuje(C)
wielką literę każdego elementu iprintf %s ...
drukuje wszystkie elementy jeden po drugim ..Aby zapisać go w innej zmiennej, można użyć
(j::)
do łączenia elementów:i użyj / użyj go później:
źródło
Oto sposób na Perla:
Może radzić sobie z ciągami o dowolnej długości:
Będzie pasować do dowolnego znaku (
.
), który pojawia się po początku łańcucha lub znaku podkreślenia ((^|_)
) i zastąpi go samą wersją wielkich liter (uc($&)
).$&
Jest specjalną zmienną, która zawiera co właśnie dopasowane. Nae
końcus///ge
zezwala na użycie wyrażeń (uc()
w tym przypadku funkcji) w ramach podstawienia ig
powoduje, że zastępuje ono wszystkie wystąpienia w wierszu. Drugie podstawienie usuwa podkreślenia.źródło
perl -pe 's/(^|_)([a-z])/uc($2)/ge'
Nie jest konieczne reprezentowanie całego łańcucha w dopasowaniu wyrażenia regularnego - sed ma
/g
modyfikator, który pozwala na przejście wielu dopasowań i zastąpienie każdego z nich:Pierwszym wyrażeniem regularnym jest
_\([a-z]\)
- każda litera po podkreśleniu; drugi pasuje do pierwszej litery w ciągu.źródło
Podaję tylko tę odpowiedź, ponieważ jest ona krótsza i prostsza niż jakakolwiek inna do tej pory.
Mówi: upcase, znak następujący po a
_
lub na początku. Nie litery nie zostaną zmienione, ponieważ nie mają wielkości liter.źródło
FooBar
ale podkreślenie powinno zostać usunięte zgodnie z instrukcjami. W każdym razie rozumiem instrukcje._
) były zamiast tego wskazywane przez przejścia wielkości liter. Biorąc pod uwagę, że „FOO_BAR” → „FOOBAR” jest wyraźnie niepoprawny (ponieważ odrzuca informacje o podziale słów), chociaż „FOO_BAR” → „FooBar” może być poprawny. (4) Podobnie mapowanie, które powoduje kolizje, wydaje się być sprzeczne z duchem pytania. Na przykład uważam, że odpowiedź, która konwertuje „DO_SPORTS” i „DOS_PORTS” na ten sam cel, jest błędna.W perlu:
Jest to również w stanie obsługiwać i18n:
źródło
Zrobiłem to w ten sposób:
i uzyskałem ten wynik:
źródło