大文字小文字変換
プログラミング向け
- camelCase
- PascalCase
- snake_case
- CONSTANT_CASE
- kebab-case
- dot.case
- Train-Case
文章向け
- UPPERCASE
- lowercase
- Title Case
- Sentence case
- iNVERSE cASE
入力した内容が保存・記録・共有されることはありません。
テキストを貼り付けると、キャメルケースやスネークケースからタイトルケース、センテンスケースまで一度に変換結果を表示します。処理はすべてブラウザ内で行われます。
使い方
- テキストまたは識別子を貼り付けます。
- プログラミング向けと文章向けに分けて、すべての形式が同時に生成されます。
- 必要な形式をコピーします。
各ケースとそれぞれの使いどころ
camelCaseは小文字で始まり、2語目以降の先頭を大文字にします。JavaScript、Java、Swiftの変数や関数の慣習です。PascalCaseは最初の語も大文字にし、一般に型、クラス、コンポーネントに使われます。snake_caseは小文字の語をアンダースコアでつなぎ、Python、Ruby、RustやSQLの識別子で標準です。SCREAMING_SNAKE_CASEはそれを大文字にしたもので、ほぼ定数と環境変数だけに使われます。
kebab-caseは小文字の語をハイフンでつなぎ、アンダースコアが扱いにくい、あるいは見えにくい場所で使われます。URLのスラッグ、CSSのクラス名やカスタムプロパティ、HTMLの属性、コマンドラインのフラグ、npmのパッケージ名などです。dot.caseは設定のキーや名前空間付きの設定項目に登場します。
どれを選ぶかは、好みの問題であることはほとんどありません。エコシステムごとに慣習があり、リンターがそれを強制します。ケースの違う識別子は、置かれたファイルの中で異質に見えてしまいます。
難しいのは単語の分割
単語の区切りさえわかればケースの変換は簡単で、単純な実装がつまずくのはその区切りを見つける部分です。入力はアンダースコア、ハイフン、ドット、スペースで分割され、さらに大文字・小文字の境界でも分割されるので、userNameとuser_nameはどちらも同じ2つの単語として解析されます。
連続した大文字は、1文字ずつではなく1つの単語として扱います。XMLHttpRequestはXML、Http、Requestに分かれてx_m_l_http_requestではなくxml_http_requestになり、getUserIDのIDもひとまとまりのまま残ります。規則は、連続した大文字は後ろに小文字が続く場合、その1文字手前で終わるというもので、これによってHttpのHが前の単語の終わりではなく新しい単語の始まりになります。
数字は直前の単語にくっつくので、parseInt32はparseとInt32に分かれます。先頭と末尾の区切り文字は取り除かれ、連続した区切り文字は1つにまとめられます。
文章向けのケースと日本語
Title Caseは単にすべての語を大文字で始めるものではありません。英語のスタイルガイドでは、冠詞、短い前置詞、等位接続詞は、タイトルの最初か最後に来る場合を除いて小文字のままにします。そのためThe Lord Of The RingsではなくThe Lord of the Ringsになります。どこで線を引くかはガイドによって異なり、特に4文字以上の前置詞で意見が分かれるので、重要な場合は自分の使うガイドを確認してください。Sentence caseは最初の語だけを大文字にして残りはそのままにするもので、見出しの表記ルールとして採用されることが増えています。
日本語、中国語、韓国語には大文字と小文字の区別がないため、これらの文字はそのまま通過します。混在したテキストでは、ラテン文字の部分だけが変換されます。日本語などのCJK文字の連なりは1つの単語として扱います。単語に分けるには辞書と形態素解析器が必要で、境界を当て推量すれば、自信満々に間違った出力を生むことになるからです。
往復変換では情報が失われる
識別子を別のケースに変換してから元に戻しても、最初と同じになるとは限りません。snake_caseからcamelCaseへ変換して戻すのは安全です。アンダースコアの区切りが大文字・小文字の境界として残るからです。しかし略語を含むものはそうはいきません。HTTPServerはhttp_serverになり、それを戻すとHttpServerになります。HTTPが略語だったという情報は大文字の並びにしか存在せず、小文字にした時点で失われたのです。
これはコードベース全体で名前を変更するときに問題になります。変換を連鎖させるのではなく、元の名前から一度だけ変換すべき理由がここにあります。
そもそも、なぜ流儀が分かれたのか
どの記法が優れているというわけではありません。歴史的な偶然が、そのままコミュニティの標準として固まったものです。Cとその流れをくむUnixの文化が小文字とアンダースコアを好んだのは、初期のリンカが大文字小文字を区別せず、長い名前にコストがあったからです。camelCaseはSmalltalkが広め、Javaが受け継ぎ、JavaScriptがJavaに寄せた結果ふたたび受け継ぎました。
Pythonはスタイルガイドで関数と変数にsnake_case、クラスにPascalCaseを明文化しました。あの文書の影響力こそが、Pythonのコードがプロジェクトをまたいでも一貫して見える理由であり、より古い言語が達成できなかったことです。CSSとHTMLがkebab-caseに落ち着いたのは、文法が大文字小文字を区別しないことと、識別子を持たない言語ではハイフンが自然に読めることの両方によります。
実務上の結論は、正しい記法とは周囲のエコシステムが使っているものだ、ということです。camelCaseだらけのPythonファイルが読みにくいのは、その記法が劣っているからではなく、そのプロジェクトのほかのすべてのファイルが従っているパターンを壊すからです。
2つの流儀が接する境界を越える
現実のシステムには、たいてい記法が切り替わる継ぎ目が少なくとも1か所あります。PostgreSQLのスキーマは、引用符なしの識別子が小文字に畳まれるためsnake_caseになり、その前段のJSON APIは普通camelCase、それを受け取るReactのコンポーネントはPascalCaseでpropsはcamelCase、そして描画されるCSSクラスはkebab-caseです。
その継ぎ目で、1か所だけ変換するのが扱いやすさの要点です。ORMやシリアライズのライブラリはほぼすべて、まさにこのための命名規則の設定を用意しており、フィールドを1つずつ手で対応づけるよりずっと確実です。手作業のマッピングは、打ち間違いと「静かに消えるプロパティ」の発生源になります。
避けたいのは、二度変換することと、層ごとに別々の方向へ変換することです。フィールドがuser_nameとして届き、クライアントでuserNameになり、user_nameを期待するAPIにuserNameのまま返される。このずれは、たいていエラーではなく「値が黙って無視される」という形で現れます。
コードベース全体の名前を壊さずに変える
名前の変更が単なる検索と置換で済むのは、最も単純な場合だけです。同じ識別子が、変数として、シリアライズに使われる文字列として、データベースの列として、URLのパスとして、そしてドキュメントの中に現れることがあり、それらは同じ変更ではありません。変数名の変更は安全ですが、シリアライズされるキーの変更はAPIの破壊的変更です。
うまくいく手順は、変換を連鎖させるのではなく、元の名前から一度だけ変換することです。略語は往復に耐えられません。HTTPServerはhttp_serverになり、戻すとHttpServerになります。まず対応表全体を生成し、目で確認してから適用しましょう。
恒久的な対策はリンターです。ESLint、Ruff、golintとその同類は、新しいコードに命名規則を強制できるので、大きな改名を一度終えたあとに同じ問題が再発するのを防げます。
すべての言語で大文字小文字が単純なわけではない
大文字化と小文字化はロケールに依存する操作で、よく知られた例がいくつかあります。トルコ語ではiの大文字は点付きで、Iを小文字にすると点なしの文字になります。そのため、トルコ語ロケールで大文字小文字を無視した比較を行うと、英語では同一に見える識別子が一致しないことがあります。よくある防御策は、対象が文章ではなく識別子であるときは、ロケールに依存しない方法で小文字化することです。
ドイツ語のßは大文字にするとSSになるので、操作によって文字列の長さが変わり、往復させても元に戻りません。ギリシャ語のシグマは、語末かどうかで小文字の形が2つあります。これらはASCIIの識別子には影響せず、コードの大半はそれで済みますが、利用者が入力したテキストにはすべて影響します。
ここでの変換はラテン文字を対象としており、日本語、中国語、韓国語の文字はそのまま残します。これらの文字体系には大文字と小文字の区別がないからです。
コードより長く残るのは名前
記法の変換は機械的な作業ですが、どの語を選ぶかはそうではありません。そして読み手が本当に苦労するのは語のほうです。一貫したスタイルはコードベースをひと目で読めるようにしますが、一貫して適用された悪い名前はやはり悪い名前です。改名は今なら安く、識別子がAPIとデータベースの列と3つのダッシュボードに広がったあとでは高くつきます。
いくつかの慣習は労力に見合います。真偽値は問いの形が明確になる接頭辞を付けると読みやすくなります。isActive、hasPermission、canEditのようにです。単なるactiveでは状態なのか動作なのか曖昧です。コレクションは複数形、単体は単数形にして、userListではなくusersとuserにします。単位は名前に入れます。timeoutMs、sizeBytes、priceCentsのようにです。
判別できなくなるほど省略するのは避けましょう。usrMgrで節約した2文字は、この先の読み手全員の一瞬を奪います。しかもコードベースの半分がuser、もう半分がusrと書けば検索が当てになりません。同義語の不統一も同じです。fetch、get、load、retrieveが4つのモジュールで同じ仕事をしているのは、永遠に払い続ける小さな税であり、1つに決めるのは無料です。
よくある質問
- 識別子の単語はどのように判定されますか?
- 区切り文字と大文字小文字の境界で分割し、頭字語はまとめて扱います。XMLHttpRequest は x_m_l_http_request ではなく xml_http_request となり、getUserID の ID も I と D に分割されません。
- タイトルケースはなぜ全単語を大文字にしないのですか?
- スタイルガイドでは、短い接続語は先頭または末尾でない限り小文字のままにします。そのため「the lord of the rings」は「The Lord Of The Rings」ではなく「The Lord of the Rings」になります。対象語の一覧はガイドによって異なるため、細部はご利用のガイドをご確認ください。
- 日本語・中国語・韓国語はどうなりますか?
- これらの文字体系には大文字小文字の区別がないため、そのまま維持されます。混在したテキストではラテン文字部分のみが変換され、CJKの連続部分は辞書なしに分割できないため1つの単語として扱われます。
- 名前のリストをまとめて変換できますか?
- はい。プログラミング向けの形式は行単位で適用されるため、識別子のリストを1行ずつ変換できます。文章向けの形式はテキスト全体に適用され、改行はそのまま維持されます。
- テキストは送信されますか?
- いいえ。変換はすべてブラウザ内で実行されるため、データが端末外に出ることはありません。
最終更新:
操作手順、期待した結果、実際の結果を記載してください。秘密情報や個人情報は削除してください。
