밑줄을 PascalCase, 즉 UpperCamelCase로 변환


28

다음과 같은 문자열이있는 경우 :

"this_is_the_string"

bash 스크립트 내부에서 PascalCase, 즉 UpperCamelCase로 변환하여 다음과 같이 표시하려고합니다.

"ThisIsTheString"

lowerCamelCase로 변환하는 방법은 다음과 같습니다.

"this_is_the_string" | sed -r 's/([a-z]+)_([a-z])([a-z]+)/\1\U\2\L\3/'

불행히도 나는 이것을 수정하기 위해 정규 표현식에 익숙하지 않습니다.


(1)이 질문 (그리고 지금까지 제시된 답변들)에 관한 한 이것은 중요하지 않지만, FYI \U\2는 두 번째 그룹에서 찾은 텍스트를 ALL CAPS로 변환하여 삽입합니다. \u\2문장 문자에 첫 문자 만 대문자를 사용하여 텍스트를 삽입하는 을 (를 ) 비교하십시오 . (2) 아래에 제시된 모든 예제는 "this_is_a_string"을 "ThisIsAString"으로 변환합니다. 이는 요청한 내용이지만 읽기가 약간 어렵습니다. 한 글자로 된 특수한 경우 (하위 문자열)에 대한 요구 사항을 수정하려고 할 수 있습니다. … (계속)
Scott

(계속) ... (3) 한 줄에 하나의 문자열 만 있습니까? 그리고 그것은 항상 줄의 첫 번째 (또는 유일한 ) 텍스트입니까? 줄의 시작 부분에없는 문자열이 있으면 아래 답변이 lowerCamelCase로 변환됩니다. 수정하려면 Janis의 답변을으로 변경 (^|_)하십시오 (\<|_).
Scott

답변:


44
$ echo "this_is_the_string" | sed -r 's/(^|_)([a-z])/\U\2/g'            
ThisIsTheString


(^|_)문자열의 시작 부분 또는 밑줄 (첫 번째 그룹
([a-z])단일 소문자-두 번째 그룹)

\U\2두 번째 그룹을
g전체적으로 대문자로 대체 하여 대체 패턴 .


4
참고 : \UPOSIX에 대한 GNU 확장입니다.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

1
참고로, 숫자도 캡처해야합니다 sed -r 's/(^|[-_ ]+)([0-9a-z])/\U\2/g'. 따라서 "this_is_2nd_string" 과 같은 문자열도 작동합니다.
pinkeen

9

을 사용하고 있으므로 bash문자열을 변수에 저장하면 쉘 전용으로 수행 할 수도 있습니다.

uscore="this_is_the_string_to_be_converted"
arr=(${uscore//_/ })
printf %s "${arr[@]^}"
ThisIsTheStringToBeConverted

${uscore//_/ }모두 _공백으로 바꾸고 (....)문자열을 배열로 분할하고 ${arr[@]^}각 요소의 첫 글자를 대문자로 변환 한 다음 printf %s ..모든 요소를 ​​하나씩 인쇄합니다.
낙타로 묶인 문자열을 다른 변수에 저장할 수 있습니다.

printf -v ccase %s "${arr[@]^}"

나중에 사용 / 재사용하십시오. 예 :

printf %s\\n $ccase
ThisIsTheStringToBeConverted

또는 zsh:

uscore="this_is_the_string_to_be_converted"
arr=(${(s:_:)uscore})
printf %s "${(C)arr}"
ThisIsTheStringToBeConverted

(${(s:_:)uscore})문자열을 _배열로 분할하고 (C)각 요소의 첫 글자를 대문자 로 바꾸고 printf %s ...모든 요소를 ​​하나씩 인쇄합니다.
다른 변수에 저장하려면 (j::)요소를 결합하는 데 사용할 수 있습니다 .

ccase=${(j::)${(C)arr}}

나중에 사용 / 재사용하십시오.

printf %s\\n $ccase
ThisIsTheStringToBeConverted

8

펄 방식은 다음과 같습니다.

$ echo "this_is_the_string" | perl -pe 's/(^|_)./uc($&)/ge;s/_//g'
ThisIsTheString

임의 길이의 문자열을 처리 할 수 ​​있습니다.

$ echo "here_is_another_larger_string_with_more_parts" | 
    perl -pe 's/(^|_)./uc($&)/ge;s/_//g'
HereIsAnotherLargerStringWithMoreParts

.문자열의 시작 또는 밑줄 ( (^|_)) 뒤에 오는 모든 문자 ( ) 와 일치하고 대문자 ( ) 자체로 바꿉니다 uc($&). 는 $&단지 일치 된 무엇이든 들어있는 특수 변수입니다. e의 말은 s///ge표현의 사용합니다 (허용 uc()대체 내이 경우 기능)과는 g그것을 대체하게 모든 라인에서 발생합니다. 두 번째 대체는 밑줄을 제거합니다.


펄에 관해서는 밑줄이있는 텍스트를 "동기화" 하는 펄 모듈 String :: CamelCase도 있습니다.
don_crissti

@ don_crissti ooh, 이것에 딱 맞습니다. 감사.
terdon

짧은 펄 :perl -pe 's/(^|_)([a-z])/uc($2)/ge'
이삭

6

정규 표현식 일치로 전체 문자열 을 나타낼 필요는 없습니다. sed에는 /g여러 일치 항목을 살펴보고 각각을 바꿀 수 있는 수정자가 있습니다.

echo "this_is_the_string" | sed 's/_\([a-z]\)/\U\1/g;s/^\([a-z]\)/\U\1/g'

첫 번째 정규 표현식은 _\([a-z]\)-밑줄 뒤의 각 문자입니다. 두 번째 문자는 문자열의 첫 번째 문자와 일치합니다.


3

나는 지금까지 다른 어떤 것보다 더 짧고 단순하기 때문에이 답변을 넣었습니다.

sed -re "s~(^|_)(.)~\U\2~g"

대문자 _, 시작 또는 뒤에 오는 문자 . 문자가없는 문자는 변경되지 않습니다.


1
"모든 것이 가능한 한 단순해야하지만 단순하지 않아야합니다." – 알버트 아인슈타인. 이것은 다른 답변과 동일하지 않습니다. 귀하의 답변은 "FOO_BAR"을 "FOOBAR"로 변환하고 다른 답변은 혼자 남겨 둡니다.
Scott

@ 스콧 아 그래, 나는 그것을 생각하지 않았다.
ctrl-alt-delor

1
@Scott 원하는 행동이 아닌가? 이상적 FooBar으로는되어야하지만 지침에 따라 밑줄을 제거해야한다고 생각합니다. 어쨌든 지시 사항을 이해합니다.
terdon

2
(계속)… (3) 질문의 정신은 문자열을 변환하여 밑줄 ( _)로 표시된 단어 구분이 대소 문자 전환으로 표시되는 것이 분명하다고 생각합니다 . "FOO_BAR"→ "FooBar"는 정확할 수 있지만 "FOO_BAR"→ "FOOBAR"은 (단어 분리 정보를 버림에 따라) 명확하지 않습니다. (4) 마찬가지로, 충돌을 일으키는 매핑은 문제의 정신에 위배되는 것으로 보입니다. 예를 들어“DO_SPORTS”와“DOS_PORTS”를 동일한 대상으로 변환하는 답변이 잘못되었다고 생각합니다.
Scott

1
(다시 계속) ... (5) 충돌을 일으키지 않는 정신으로“foo_bar”와“FOO_BAR”이 같은 것으로 매핑되어서는 안되므로“FOO_BAR”→“FooBar”에 반대합니다. . (6) 더 큰 문제는 네임 스페이스라고 생각합니다. Blaise가 활성화 된 이후로 Pascal에서 프로그래밍하지는 않았지만 C / C ++에서는 일반적으로 기본적으로 소문자 (snake_case 및 CamelCase 포함) 인 식별자는 일반적으로 컴파일러의 도메인이며 대문자는 식별자입니다. 전 처리기의 도메인. 그래서 OP가 ALL_CAPS 식별자를 고려하지 않기를 원한 것 같습니다.
Scott

1

펄에서 :

$ echo 'alert_beer_core_hemp' | perl -pe 's/(?:\b|_)(\p{Ll})/\u$1/g'
AlertBeerCoreHemp

이것은 또한 i18n 가능합니다 :

$ echo 'алерт_беер_коре_хемп' | perl -CIO -pe 's/(?:\b|_)(\p{Ll})/\u$1/g'
АлертБеерКореХемп

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.