camelCase로 변환


34

도전

나는 다른 날 Google의 Java 스타일 가이드를 읽고 임의의 문자열을 camelCase 표기법으로 변환하기 위해 알고리즘을 우연히 발견했습니다. 이 도전에서는 코드 골프 도전에 대한 경쟁이 치열한 Java 제출을 작성할 때 머리 에이 모든 것을 수행하지 않기 때문에이 알고리즘을 구현해야합니다.

참고 : 알고리즘을 약간 조정했습니다. 아래에 지정된 것을 사용해야합니다.

알고리즘

임의의 입력 문자열로 시작하여 다음 조작을 적용하십시오.

  1. 모든 아포스트로피 제거 `'
  2. 에서 분할하여 결과를 단어로 분할
    • 영숫자가 아니고 숫자가 아닌 문자 [^a-zA-Z0-9]
    • 양쪽에 소문자로 둘러싸인 대문자. abcDefGhI jk예를 들어 수율abc Def Ghi jk
  3. 모든 단어를 소문자로 사용하십시오.
  4. 첫 단어를 제외한 모든 문자의 첫 문자
  5. 모든 단어를 다시 합치십시오.

추가 사항

  • 입력은 인쇄 가능한 ASCII 만 포함합니다.
  • 숫자가 단어의 첫 글자 인 경우 그대로두고이 단어의 다른 단어를 대문자로 표시하지 마십시오.
  • 입력은 항상 하나 이상의 문자를 갖습니다.

규칙

  • 기능 또는 전체 프로그램이 허용됩니다.
  • 입 / 출력의 기본 규칙 .
  • 표준 허점이 적용됩니다.
  • 이것은 이므로 바이트 수가 가장 적습니다. Tiebreaker는 이전에 제출되었습니다.

테스트 사례

"프로그래밍 퍼즐 및 코드 골프"-> "programmingPuzzlesCodeGolf"
"XML HTTP 요청"-> "xmlHttpRequest"
"iOS에서 IPv6을 지원합니까?" -> "Ipv6OnIos 지원"
"일부 w, 아포스트로피 및 문장 부호"-> "someThingW1ApostrophesAndPuncTuation"
"아무것도 특별한"-> "nothingSpecial"
"5pecial ca5e"-> "5pecialCa5e"
"1337"-> "1337"
"1337-spEAk"-> "1337 말하기"
"whatA mess"-> "whataMess"
"abcD"-> "abcd"
"a"-> "a"
"B"-> "b"

행복한 코딩!


3
흥미롭게도 이것이 "camelCase"라는 것을 몰랐습니다. 이름은 내가 생각하는 것입니다 ...
Ashwin Gupta

4
더있다 : snake_case&PascalCase
Martijn

14
snake_case물론 파이썬 때문에 @Martijn . FORTH도 FORTHCASE있고 APL은unreadable in any case
cat

테스트 케이스 4는 ApostropheS출력에 있어야합니다.
Titus

@Titus 아니오, 맞습니다. 입력이 분리되기 전에 아포스트로피가 제거됩니다.
Denker

답변:


13

레티 나 , 56 바이트

바이트 수는 ISO 8859-1 인코딩을 가정합니다.

T`'\`
S_`\W|_|(?<=[a-z])(?=[A-Z][a-z])
T`L`l
T`l`L`¶.
¶

온라인으로 사용해보십시오!

설명

이것은 사양을 문자 그대로 구현합니다.

T`'\`

아포스트로피와 백틱을 제거하십시오.

S_`\W|_|(?<=[a-z])(?=[A-Z][a-z])

문자열을 단어가 아닌 문자로 나누십시오 (정규식에서는 숫자와 밑줄도 제외) 또는 왼쪽에 소문자가 있고 오른쪽에 소문자가있는 밑줄 또는 위치 이렇게하면 문자가 아닌 두 자리가 아닌 문자가 한 행에 있거나 문자열의 시작 부분에서 더 중요한 경우 빈 세그먼트가 만들어집니다. 우리는 _옵션 을 가진 사람들을 제거합니다 . 여기서 "분할"이란 나머지 각 부분을 자체 라인에 배치하는 것을 의미합니다.

T`L`l

모든 것을 소문자로 변환하십시오.

T`l`L`¶.

줄 바꿈 후 발생하는 각 문자를 대문자로 변환하십시오. 첫 번째 단어 앞에 줄 바꿈이 없기 때문에 첫 단어를 편리하게 건너 뜁니다.

줄 바꿈을 제거하여 모든 것을 다시 결합하십시오.


넌 날 이겼어 좋은 것!
mbomb007

이 질문은 조금 이상 할 수 있지만 .... 대답이 당신보다 짧고 Retina에 있으면 답변을 게시해야합니까? 귀하의 답변이 나타나기 전에 작업 중이었지만 지금은 게시해야하는지 모르겠습니다.
daavko

5
@ daavko 물론 게시하십시오 (일반적으로 접근 방식이 기존 답변과 어떻게 다른지에 따라 결정합니다 ... 어딘가에서 깎인 바이트와 똑같은 것이면 일반적으로 해당 답변에 대해 언급하지만 훨씬 짧습니다. 다른 접근 방식의 경우 별도의 답변을 게시합니다).
Martin Ender

2
@daavko 그래도 둘러보기가 필요합니다. 귀하의 답변은 대문자를 유지하지는 않습니다 Thing.
Martin Ender

1
@ MartinBüttner 오 ... 그런걸 몰랐어요. 글쎄, 나는 다른 도전에 성공적으로 대답 할 것이다.
daavko

11

자바, 198190 바이트

\W+==를 잊어 버렸기 때문에 +3 바이트 [^a-zA-Z0-9_]+가 일치해야합니다.[^a-zA-Z0-9]+

user20093 덕분에 -11 바이트 - / ?:대신ifelse

왜냐하면, 자바.

s->{String[]a=s.replaceAll("`|'","").split("[\\W_]+|(?<=[a-z])(?=[A-Z][a-z])");s="";for(String w:a){String t=w.toLowerCase();s+=a[0]==w?t:t.toUpperCase().charAt(0)+t.substring(1);}return s;}

이것은 람다입니다. 이렇게 전화하십시오 :

UnaryOperator<String> op = s->{String[]a=s.replaceAll("`|'","").split("[\\W_]+|(?<=[a-z])(?=[A-Z][a-z])");s="";for(String w:a){String t=w.toLowerCase();s+=a[0]==w?t:t.toUpperCase().charAt(0)+t.substring(1);}return s;};
System.out.println(op.apply("Programming Puzzles & Code Golf"));

읽을 수있는 버전 :

public static String toCamelCase(String s) {
    String[] tokens = s
            .replaceAll("`|'", "") // 1. Remove all apostrophes
            .split("[\\W_]+|(?<=[a-z])(?=[A-Z][a-z])"); // 2. Split on [\W_]+ or between [a-z] and [A-Z][a-z]
    s = ""; // Reusing s for building output is cheap
    for (String token : tokens) {
        String lowercaseToken = token.toLowerCase(); // 3. Lowercase every word
        s += tokens[0].equals(token)?lowercaseToken:lowercaseToken.toUpperCase().charAt(0) + lowercaseToken.substring(1); // 4. Uppercase first char of all but first word
        // ^ 5. Join all words back together
    }
    return s;
}

1
그것은 스위프트가 아닙니다 ...
CalculatorFeline

2
프로그래밍 퍼즐 및 코드 골프에 오신 것을 환영합니다! 이것은 좋은 첫 번째 대답입니다!
Alex A.

1
@CatsAreFluffy 무엇?
고양이

조건문 (if / else)을 조건식 (? :)으로
바꾸면

@ user902383이 -11 바이트에 추가 된 것을 놓친 방법을 모르겠습니다. 불행히도 _토큰 구분 기호 로 일치시키기 위해 3을 추가해야했습니다 .
CAD97

10

자바 스크립트 (ES6) 156 154 152 148 145 141 140 바이트

@Neil (6 바이트), @ETHproductions (3 바이트) 및 @ edc65 (7 바이트)에게 감사합니다.

a=>a[r='replace'](/`|'/g,a='')[r](/[a-z](?=[A-Z][a-z])/g,'$& ')[r](/[^\W_]+/g,b=>a+=(a?b[0].toUpperCase():'')+b.slice(!!a).toLowerCase())&&a

아포스트로피를 제거한 다음 대체 문자를 사용하여 특수 문자 / 분포 된 대문자로 분할 한 다음 적절한 케이스와 결합합니다. 불행하게도, toLowerCase()그리고 것은 toUpperCase()짜증나 긴 및 하드 여기 피할 수 있습니다 ...


1
나는 당신의 b.slice(i>0)접근 방식이 물에서 빠져 나오는 다른 접근법을 연구하고 있었지만, 그 동안 내 정규식이 /[A-Z]?([a-z0-9]|[0-9A-Z]{2,})+([A-Z](?![a-z]))?/g귀하의 독창적 인 replace접근 방식 보다 2 바이트를 절약하는 것처럼 보입니다 .
Neil

1
아니면 replace직접 2 바이트를 절약 할 수도 있습니다.replace(/[a-z](?=[A-Z][a-z])/g,'$& ')
Neil

1
일반적 match...map으로 대체 할 수있다replace
edc65

1
@ edc65이 방법으로 최소 160 바이트를 얻습니다.a=>a.replace(/`|'/g,'').replace(/[a-z](?=[A-Z][a-z])/g,'$& ').replace(/[\W_]*([a-z0-9]+)[\W_]*/gi,(_,b,i)=>(i?b[0].toUpperCase():'')+b.slice(i>0).toLowerCase())
ETHproductions

2
반면에, 나는 b=>a+=(a?b[0].toUpperCase():'')+b.slice(!!a).toLowerCase()당신에게 또 다른 4 바이트를 절약한다고 생각합니다.
Neil

7

정력, 69 68 66

:s/[`']//g<cr>:s/[a-z]\zs\ze[A-Z][a-z]\|\W\|_/\r/g<cr>o<esc>guggj<C-v>GgU:%s/\n<cr>

Vim이 Perl보다 짧습니까?! 이 광기는 무엇입니까?

:s/[`']//g<cr>           remove ` and '
:s/                      match...
 [a-z]\zs\ze[A-Z][a-z]   right before a lowercase-surrounded uppercase letter
 \|\W\|_                 or a non-word char or underscore
 /\r/g<cr>               insert newlines between parts
o<esc>                   add an extra line at the end, necessary later...
gugg                     lowercasify everything
j                        go to line 2 (this is why we added the extra line)
<C-v>G                   visual select the first char of all-but-first line
gU                       uppercase
:%s/\n<cr>               join all lines into one

쓸모없는 키 입력을 발견 한 Neil 에게 감사드립니다 !


나는 왜 마지막 :s%있지만 왜 처음 두 부분의 불일치를 볼 수 있습니까?
Neil

@Neil Bah, 근육 기억력. 감사!
Doorknob

5
+1
cat

나는 이것을 내 .vimrc
moopet에

1
@fruglemonkey 1 :%j<cr>은 동일하고 짧습니다. 2. 그것은 줄 사이에 공백을 추가합니다.
손잡이

5

Mathematica 10.1, 101 바이트

""<>(ToCamelCase@{##2}~Prepend~ToLowerCase@#&@@StringCases[StringDelete[#,"`"|"'"],WordCharacter..])&

undocumented를 사용합니다 ToCamelCase.이 기능은 비슷하게 작동 Capitalize하지만 다른 문자는 소문자로 설정합니다.


10.3.0.에 없습니다.
시몬스

ToCamelCase[n_,m_]:=n<>Capitalize/@m맞습니까? 그런 것 같습니다. 왜 작동 Prepend할 때 사용 #~ToCamelCase~{##2}합니까?
CalculatorFeline

@CatsAreFluffy 저에게주는ToCamelCase::argx: ToCamelCase called with 2 arguments; 1 argument is expected.
LegionMammal978

CamelCase는 어떻게 작동합니까? 그냥 ToCamelCase[n_]:=""<>Capitalize/@n?
CalculatorFeline


5

줄리아, 98 89 바이트

s->lcfirst(join(map(ucfirst,split(replace(s,r"['`]",""),r"[a-z]\K(?=[A-Z][a-z])|\W|_"))))

이것은 문자열을 받아들이고 문자열을 반환하는 익명 함수입니다. 호출하려면 변수에 지정하십시오.

여기 방법은 손잡이의에서와 동일한 펄 대답 : replace빈 문자열을 작은 따옴표와 역 따옴표 split필요한 경우 일치하는 정규 표현식에 배열로, 배열을 통해 함수는 각 요소의 첫 글자를 대문자로 배열 다시 문자열 로 변환하고 결과를 첫 문자를 소문자로 변환합니다.mapucfirstjoinlcfirst


나는 Julia를 항상 더 기능적이고 흥미로운 Python으로 좋아했지만 end구문이 싫습니다 . 어쩌면 난 그냥 입력, 모든 것을 익명 함수를 다음 나는 결코 사용합니다 end: D
고양이

4

Perl 67 + 1 = 68 바이트

y/'`//d;s/([a-z](?=[A-Z][a-z]))|\W|_/$1 /g;$_=lc;s/^ +| +(.)/\u$1/g

-p플래그가 필요하고 -l여러 줄이 필요합니다 .

$ perl -pl camelCase.pl input.txt
programmingPuzzlesCodeGolf
xmlHttpRequest
supportsIpv6OnIos:
someThingW1thApostrophesAndPuncTuation
nothingSpecial
5pecialCa5e
1337
1337Speak
abcd

작동 방식 :

y/'`//d;                            # Remove ' and `
s/([a-z](?=[A-Z][a-z]))|\W|_/$1 /g; # Replace according to '2. Split...' this will create
                                    #   a space separated string.
$_=lc;                              # lower case string
s/^ +| +(.)/\u$1/g                  # CamelCase the space separated string and remove any
                                    #   potential leading spaces.

2

펄, 87 80 78 바이트

y/'`//d;$_=join'',map{ucfirst lc}split/[a-z]\K(?=[A-Z][a-z])|\W|_/,$_;lcfirst

-p플래그에 바이트가 추가되었습니다 .

먼저 y///음역 연산자를 사용 하여 입력의 d모든 '`문자 를 추출합니다 .

y/'`//d;

그런 다음 코드의 고기가옵니다.

                         split/[a-z]\K(?=[A-Z][a-z])|\W|_/,$_;

( 일치 문자열을 $_사용하여 적절한 위치에 입력 문자열 을 분리하여 \K실제 일치에서 선행하는 부분을 제외시킵니다)

          map{ucfirst lc}

(문자열의 각 분할 부분을 매핑하고 전체 문자열을 소문자로 만든 다음 수정 된 문자열의 첫 번째 문자를 대문자로 만듭니다)

$_=join'',

(빈 문자열에 합류 $_하고 마지막에 인쇄되는 마술 밑줄에 다시 할당 )

마지막으로, 우리는 첫 글자 를 정규식 일치\l 시키고 내장 문자열대체 문자열에서 사용 하여 이전 방법보다 2 바이트를 절약 하여 소문자를 소문자 로 만듭니다.

lcfirst

7 바이트 ( -> )의 @ MartinBüttner 에게 감사합니다 ![^a-zA-Z\d]\W|_


1
내가 부러워하는 방법 \K...;)
Martin Ender

2

루아, 127 바이트

t=''l=t.lower z=io.read()for x in z:gmatch('%w+')do t=t..(t==''and l(x:sub(1,1))or x:sub(1,1):upper())..l(x:sub(2))end return t

stdin에서 문자열을 받아 낙타 화 된 결과를 반환합니다.

변수에 모든 것을 저장하는 것이 비효율적이라고 생각할 때 아마도 더 나은 솔루션을 찾을 것입니다.

그러나 어쨌든 일반적으로 매우 간단합니다.

 z:gmatch('%w+')

이것은 나에게 약간의 바이트를 절약 한 아름다움입니다. gmatch는 패턴을 기반으로 문자열을 분할합니다. %w+이는 영숫자 만 가져 옵니다 .

그 후에는 간단한 문자열 연산입니다. string.upper, string.lower 및 done.


2

PHP, 145 (122) 133 바이트

<?=join(split(" ",lcfirst(ucwords(strtolower(preg_replace(["#`|'#","#\W|_#","#([a-z])([A-Z][a-z])#"],[""," ","$1 $2"],$argv[1]))))));

파일을 저장하고 CLI에서 호출하십시오.
단일 명령 행 인수에서 입력을 가져옵니다. 필요한 경우 따옴표와 공백을 이스케이프 처리하십시오.

고장

<?=                 // 9. print result
join(split(" ",     // 8. remove spaces
    lcfirst(        // 7. lowercase first character
    ucwords(        // 6. uppercase first character in every word
    strtolower(     // 5. lowercase everything
    preg_replace(
        ["#`|'#",   "#\W|_#",   "#([a-z])([A-Z][a-z])#"],
        ["",        " ",        "$1 $2"],
        // 2. replace apostrophes with empty string (remove them)
                    // 3. replace non-word characters with space
                                // 4. insert space before solitude uppercase
        $argv[1]    // 1. take input from command line
    ))))
));

lcfirst이를 단일 명령으로 줄이고 23 바이트를 절약 할 수있었습니다.
아포스트로피를 수정하는 데 추가 교체 사례의 경우 11 바이트가 소요됩니다.


1

코 틀린 , 160 바이트

fun a(s: String)=s.replace(Regex("['`]"),"").split(Regex("[\\W_]+|(?<=[a-z])(?=[A-Z][a-z])")).map{it.toLowerCase().capitalize()}.joinToString("").decapitalize()

저의 목표는 다른 "대체 자바"인 스칼라 (Scala)가되었으므로 결과에 다소 만족합니다. Java 답변 에서 정규식을 훔쳤습니다 .

다음과 같이 테스트하십시오.

fun main(args: Array<String>) {
    val testCases = arrayOf(
            "Programming Puzzles & Code Golf",
            "XML HTTP request",
            "supports IPv6 on iOS?",
            "SomeThing w1th, apo'strophe's and' punc]tuation",
            "nothing special",
            "5pecial ca5e",
            "1337",
            "1337-spEAk",
            "abcD",
            "a",
            "B")
    testCases.forEach { println(a(it)) }

}

이 시점에서 나는 모든 사람이 최적화 된 정규 표현식을 "빌리 \W|_|(?<=[a-z])(?=[A-Z][a-z])거나 " 또는 약간 수정 한다고 생각합니다 . [\W_]+
CAD97

당신은지도와 확장 기능에 대한 몇 가지 저장할 수 있습니다fun String.a()=replace(Regex("['`]"),"").split(Regex("[\\W_]+|(?<=[a-z])(?=[A-Z][a-z])")).joinToString(""){it.toLowerCase().capitalize()}.decapitalize()
포스

1

스칼라 181 170 144

def f(s:String)={val l=s.replaceAll("'|`","")split("[\\W_]+|(?<=[a-z])(?=[A-Z][a-z])")map(_.toLowerCase);l(0)+l.tail.map(_.capitalize).mkString}

시험 장치:

val testCases = List(
  "Programming Puzzles & Code Golf" -> "programmingPuzzlesCodeGolf",
  "XML HTTP request" -> "xmlHttpRequest"
  // etc
)
println(testCases.map(t=>if(t._2!=f(t._1))s"FAIL:${f(t._1)}"else"PASS").mkString("\n"))

CAD97에 대한 제안Nathan Merrill에 대한 사과 :)


1
당신은 대체하여 6 바이트를 저장할 수 있습니다 [^a-zA-Z0-9]+[\\W_]+.
CAD97

0

C 272 자

C 프로그램은 문자열을 camelCase에 인수 1로 따옴표로 전달합니다.이 문제 설명에는 많은 문제가 있습니다 ...

#define S strlen(t)
#define A isalnum(t[i])
j=0;main(i,v)char**v;{char*p=v[1],*t;char o[99]={0};while(t=strtok(p," [{(~!@#$%^*-+=)}]")){i=0;p+=S+1;while((!A)&&i<S)i++;if(i!=S){o[j]=((j++==0)?tolower(t[i++]):toupper(t[i++]));while(i<S){if(A)o[j++]=t[i];i++;}}}puts(o);}

당신은 필요 #include<string.h>에 대한 strlen, strtok그리고 toupper#include<ctype.h>에 대한 isalnum.
Mego

cygwin에서 gcc 3.4.4를 사용하여 필요하지 않았습니다. extern int를 가정하면 자동으로 연결되어야합니다.
cleblanc

./camel "Programming Puzzles & Code Golf"Cygwin에서의 (GCC 3.4.4로 컴파일), 내가 얻을 programmingPuzzlesCodeEGolf. 5.3.0과 동일한 출력.
Mego

쓰레기. 나도. 골프를 치는 동안 버그를 만들어야합니다. 지금보고 있습니다 ...
cleblanc

문제는 골프 후 다른 토크 나이저 문자열을 추가하고 충분히 테스트하지 않았다는 것입니다. strtok 호출에서 '&'를 제거하면 해당 입력에서 작동합니다.
cleblanc

0

자바 스크립트, 123 바이트

v=>v[r="replace"](/[`']/g,"")[r](/^.|.$|[A-Z][^a-z]+/g,x=>x.toLowerCase())[r](/[^a-z0-9]+./ig,x=>x.slice(-1).toUpperCase())

읽을 수있는 버전

v=>
  v.replace(/[`']/g,"")
  .replace(/^.|.$|[A-Z][^a-z]+/g,x=>x.toLowerCase())
  .replace(/[^a-z0-9]+./ig,x=>x.slice(-1).toUpperCase())

어포 스트로피를 제거하고, 첫 문자를 소문자로, 마지막 문자를 소문자로, 여러 대문자를 그룹화하고, 영숫자가 아닌 문자 + 1 개의 다른 문자 그룹과 일치시키고 대문자로 된 마지막 문자로 바꿉니다.

Mrw247의 솔루션에서 [r = "replace"] 트릭.

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