camelCaseに変換


34

チャレンジ

先日GoogleのJavaスタイルガイドを読んでいて、アルゴリズムを見つけて任意の文字列をcamelCase表記に変換しました。このチャレンジでは、コードゴルフチャレンジへの非常に競争力のあるJava提出物を作成するときに頭の中でこれらすべてを実行したくないため、このアルゴリズムを実装する必要があります。

注:アルゴリズムを少し調整しました。以下に指定されているものを使用する必要があります。

アルゴリズム

任意の入力文字列で開始し、次の操作をそれに適用します。

  1. すべてのアポストロフィを削除 `'
  2. で分割して結果を単語に分割します
    • 英数字でも数字でもない文字 [^a-zA-Z0-9]
    • 両側が小文字に囲まれている大文字。abcDefGhI jk例えば収量abc Def Ghi jk
  3. すべての単語を小文字にします。
  4. 最初の単語を除くすべての単語の最初の文字を大文字にします。
  5. すべての単語を元に戻します。

その他の注意事項

  • 入力には、印刷可能なASCIIのみが含まれます。
  • 数字が単語の最初の文字である場合は、そのままにして、この単語の他の文字を大文字にしないでください。
  • 入力には常に少なくとも1つの文字が含まれます。

ルール

  • 機能または完全なプログラムが許可されます。
  • 入出力のデフォルト規則
  • 標準の抜け穴が適用されます。
  • これはなので、バイト数が最も少なくなります。Tiebreakerは以前の提出です。

テストケース

「プログラミングパズルとコードゴルフ」->「programmingPuzzlesCodeGolf」
「XML HTTPリクエスト」->「xmlHttpRequest」
「iOSでIPv6をサポートしますか?」-> "supportsIpv6OnIos"
"SomeThing w1th、apo'strophe's and 'punc] tuation"-> "someThingW1thApostrophesAndPuncTuation"
「特別なものなし」->「特別なものなし」
"5pecial ca5e"-> "5pecialCa5e"
"1337"-> "1337"
「1337-spEAk」->「1337Speak」
「whatA mess」->「whataMess」
「abcD」->「abcd」
「a」->「a」
「B」->「b」

ハッピーコーディング!


3
興味深いことに、これが「camelCase」と呼ばれることは知りませんでした。名前は...私が思うフィッティングされた
のAshwinグプタ

4
さらにあります:snake_casePascalCase
Martijn

14
もちろんsnake_case、Pythonのせいで@Martijn 。FORTHにもありFORTHCASE、APLにありますunreadable in any case
cat

テストケース4はApostropheS出力に含まれている必要があります。
タイタス

@Titusいいえ、正しいです。アポストロフィは、入力が分割される前に削除されます。
デンカー

回答:


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

文字列を単語以外の文字(正規表現では数字とアンダースコアも除く)、またはアンダースコアまたは左に小文字があり、大文字と右に小文字がある位置で文字列を分割します。これにより、2つの非文字、非数字文字が行にある場合、またはより重要な文字列の先頭にいくつかの空のセグメントが作成されます。_オプションでそれらを取り除きます。ここで、「分割」とは、残りの各部分を独自の行に配置することを意味します。

T`L`l

すべてを小文字に変換します。

T`l`L`¶.

改行後に発生する各文字を大文字に変換します。これは、前に改行がないため、最初の単語を簡単にスキップします。

改行を取り除いて、すべてを元に戻します。


あなたは私を打ち負かした。良いですね!
mbomb007

この質問は少し奇妙かもしれませんが、...あなたの回答よりも短い場合、またRetinaで回答を投稿する必要がありますか?あなたの答えが現れる前に私はそれに取り組んでいましたが、それはうまくいきました、そして今、私はそれを投稿すべきかどうかわかりません。
-daavko

5
@daavko確かに、それを投稿します(私は通常、既存の回答に対するアプローチの違いに基づいて決定します...バイトがどこかで削られたまったく同じものである場合、私は通常その回答にコメントしますが、それよりも短い場合は別のアプローチの場合は、別の回答を投稿するだけです)。
マーティンエンダー

2
@daavkoただし、ルックアラウンドは必要です。答えは大文字の大文字/小文字を保持していないことに注意してくださいThing
マーティンエンダー

1
@MartinBüttnerああ...私はそれに気づかなかった。それでは、他の課題にうまく答えます。
-daavko

11

Java、198190バイト

\W+== を忘れて[^a-zA-Z0-9_]+、一致する必要があるため+3バイト[^a-zA-Z0-9]+

user20093のおかげで-11バイト- /の?:代わりにifelse

なぜなら、Java。

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
プログラミングパズルとコードゴルフへようこそ!これはいい最初の答えです!
アレックスA.

1
@CatsAreFluffyなに?

条件文(if / else)を条件式(?:)に置き換えると、約9バイト節約できます
-user902383

@ user902383をどのように見逃したかわかりません--11バイト追加されました。残念ながら_、トークン区切り文字として一致させるために3も追加する必要がありました。
CAD97

10

JavaScriptの(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バイト節約しているようです。
ニール

1
または、replace直接2バイトを保存することもできますreplace(/[a-z](?=[A-Z][a-z])/g,'$& ')
ニール

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バイトを節約すると信じているものを提供したいと思います。
ニール

7

vim、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

無駄なキーストロークを見つけてくれたニールに感謝します!


私は最後の理由を知ることができ:sてい%ますが、なぜ最初の二つの矛盾?
ニール

@Neil Bah、筋肉の記憶。ありがとう!
ドアノブ

5
Perlよりも読みにくくなっている+1
cat

これを.vimrcに完全に追加しています
-moopet

1
@fruglemonkey 1. :%j<cr>は同等で短くなります。2.行間にスペースが追加されます。
ドアノブ

5

Mathematica 10.1、101バイト

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

文書化されていないを使用します。これは、他の文字とToCamelCase同様に機能しますCapitalizeが、小文字に設定します。


ない10.3.0 ..中
Aシモンズ

あるToCamelCase[n_,m_]:=n<>Capitalize/@m正しいですか?それのように思えます。そして、なぜPrependwhenが#~ToCamelCase~{##2}機能するのか?
電卓

@CatsAreFluffyそれは私に与えるToCamelCase::argx: ToCamelCase called with 2 arguments; 1 argument is expected.
LegionMammal978

さて、キャメルケースはどのように機能しますか?ただToCamelCase[n_]:=""<>Capitalize/@n
電卓

@CatsAreFluffyは、参照これを
LegionMammal978

5

ジュリア、98 89バイト

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

これは、文字列を受け入れて文字列を返す匿名関数です。呼び出すには、変数に割り当てます。

ここでのアプローチは、ドアノブのと同じであるPerlの答えreplaceアポストロフィとバッククォート空の文字列で、split必要な場合にマッチする正規表現の配列に、各要素の最初の文字を大文字に配列オーバー機能、配列バック文字列に変換し、結果を最初の文字を小文字に変換します。mapucfirstjoinlcfirst


私はいつも、より機能的で面白いPythonとしてJuliaが好きでしたが、end構文は嫌いです。たぶん、すべてに匿名関数を使用するだけで、次のように入力する必要はありませんend:D
cat

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

Perl、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

@MartinBüttnerに7バイト([^a-zA-Z\d]-> \W|_)をありがとう!


1
どうして私はそれをenましく思う;; \K
マーティン・エンダー

2

Lua、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これを1つのコマンドに減らして、23バイトを節約できました。
アポストロフィの修正には、追加の置換ケースで11バイトかかります。


1

Kotlin、160バイト

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

私の目標は、もう1つの「代替Java」である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

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へと謝罪ネイサンメリル :)


1
に置き換える[^a-zA-Z0-9]+と、6バイト節約できます[\\W_]+
CAD97

0

C 272文字

Cプログラムは引数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>のためにstrlenstrtoktoupper、と#include<ctype.h>のためにisalnum
メゴ

cygwinでgcc 3.4.4を使用する必要はありませんでした。extern intを想定して、自動的にリンクする必要があります。
cleblanc

./camel "Programming Puzzles & Code Golf"cygwinの上で(GCC 3.4.4でコンパイルされた)、私が得ますprogrammingPuzzlesCodeEGolf。5.3.0と同じ出力。
メゴ

がらくた。私も。ゴルフ中にバグを作成したに違いありません。今見ています
...-cleblanc

問題は、ゴルフ後に他のトークナイザー文字列を追加し、十分にテストしていないことでした。strtok呼び出しから「&」を削除すると、その入力で機能します。
cleblanc

0

JavaScript、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つ以上の英数字以外の文字+他の1文字のグループに一致し、大文字の最後の文字で置き換えます。

[r = "replace"] Mrw247のソリューションからのトリック。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.