[Java] キャメル / スネーク / ケバブ の ケース変換プログラム


文字列 を キャメルケース にしたり、スネークケース にしたり、ケバブケース にしたりと、ケース変換 を行う Java プログラム を 自作 しましたので、ご紹介します。

ご紹介するプログラムは、 Java 標準のものだけしか使っていませんので、例えば プロジェクトの諸事情 により ライブラリを導入(あるいは最新化)できない場合でも、お役に立てるかと思います。

前置き

自作プログラム を公開しておいてなんですが、可能なら ライブラリ を使用することを おすすめします。

自前で管理するコードが減った方が 結果的にシステムのためになりますからね。

この後でプログラムをご紹介いたしますが、その前に まずは 各種ケースについての 説明 や 余談 を載せておきます。

キャメルケース とは

“theBactrianCamel” のような書き方で、
駱駝(/rp>ラクダ) のコブにちなんで camel case(/rp>キャメルケース) と呼びます。

また、先頭の文字が 大文字 なのか 小文字 なのかで 呼び方 が異なります。

“TheBactrianCamel” のように 先頭の文字 が 大文字 の場合は、
upper camel case(/rp>アッパーキャメルケース)、または PascalCase(/rp>パスカルケース) と呼びます。
プログラムの クラス名 などに使われます。

“theBactrianCamel” のように 先頭の文字 が 小文字 の場合は、
lower camel case(/rp>ローワーキャメルケース)、または 単に camelcase(/rp>キャメルケース) と呼びます。
プログラムの 変数名 などに使われます。

なお、Wikipedia の日本語ページ には
bi-capitalization(/rp>バイキャピタライゼーション)InterCaps(/rp>インターキャプス)mixedCase(/rp>ミックストケース)
といった 別名 も書いてありますが、私が知っている限るで 日本人が使っているのを 一度も目(耳)にしたことが ありません。

「InterCaps」や「CamelCase」と名前が付いたのは、比較的最近だそうで、コンピュータ関連のコミュニティで一般的になっています。
もともとは「medial capitals」という名前で、メジャーな辞書などにも載っているそうです。
( 情報ソースは Wikipedia の英語のページ です。 )

ちなみに、日本語ページに書いてある bi-capitalization(/rp>バイキャピタライゼーション) は、英語版のページ記載がない のですが、「bi capitalization」で検索すると「Camel Case」のページに転送されるようになっていました。 論文にでも書いてあった言葉なのでしょうかね?

ローワーって変じゃない?

こんなところで語っても しょうがないのですが、個人的に「lower」は「ローワー」ではなく「ロウワー」または「ロゥワー」の方が自然だと思うのです。

スペルを見ても「ローワー(/rp>ろぉわぁ)」とは読めませんし、耳で聞いてロゥワー(/rp>ろぅわぁ) と聞こえます。

「LOW」って書かれていたら、ほぼほぼ皆「ロウ」って読みますよね。

長音記号 ( ー ) は 一文字前の母音をのばす記号 だと、小学校で習いました。

つまり「ロー」と書くと、「ろお」と読むことになってしまうです。

いやいや「ろう」でしょ、長音記号は使えませんよ!

「おうさま」は「おおさま」じゃないし、「ろうじん」は「ろおじん」じゃない とも小学校で習いましたよね。

しかし、「high and low」は「ハイアンドロー」 と書き、
「low risk high return」も「ローリスクハイリターン」 と書き、
「low kick」も「ローキック」 と書くのが 一般的 です。

それがあったからなのか、「lower」も「ローワー」として広まっているようですね。

だs おっと! 本題じゃないのに 話し過ぎました(笑)

スネークケース とは

“snakes_are_dangerous” というように アンダースコア(_)を 区切記号 として 単語 をつなげて 一綴り にした表し方を、
蛇 のようだから snake case(/rp>スネークケース) と呼びます。

データベース の テーブル名 や カラム名 などに使われます。

ケバブケース とは

“kebab-is-delicious” というように ハイフン(-)を 区切記号 として 単語 をつなげて 一綴り にした表し方を、
(/rp>くさり) で繋いだようだから chain case(/rp>チェインケース) と呼びます。

スラッグ (ネットの記事などの URL に適した形式の名前) などに使われます。

ケバブの串焼き に見立てて kebab case(/rp>ケバブケース) と呼ばれることもあるようです。

※「ケバブ」 は トルコなど中東の料理 です。

ケバブのもっとも典型的な調理法は、四角形に切った肉を串に刺して焼いたものである。トルコでは、串焼きのケバブのほか、ヨーグルトを添えて食べるイスケンデルケバブ (İskender Kebabı) や、味付けした肉を重ねて固まりにし、回転させながら焼いたものを削ぎ切りしたドネルケバブ (Döner Kebabı) などのバリエーションがあり、様々な焼肉料理がケバブと総称される。なお、焼く代わりに煮込んだり、揚げたり、蒸したりする肉料理もカバブと呼ばれることがある。ウイグルのカワープも炒め肉も含めた焼肉の総称である。

「ケバブケース」という呼び方は、どうやら 最近 流行りだした呼び方のようですね。
面白いから覚えやすくて好きです。

ただ、「ケバブケース」は、プログラマ同士で話す時の、所謂(/rp>いわゆる) 俗語 だと思いますし、
業界内でも知らない人の方が 圧倒的に多そうなので、仕事で書く時は「チェインケース」と書くのが まだ暫くは正解 でしょう。

Java プログラム

/**
 * ケース変換ユーティリティ.
 *
 * @author https://so-kai-app.sakura.ne.jp/
 */
public final class CaseUtils {

	/** プライベートコンストラクタ. */
	private CaseUtils() {
	}

	/**
	 * 小文字 に変換します。
	 *
	 * @param text 変換前の文字列
	 * @return 小文字 に変換された文字列
	 */
	public static String toLowerCase(final String text) {
		return (text == null) ? null : text.toLowerCase();
	}

	/**
	 * 大文字 に変換します。
	 *
	 * @param text 変換前の文字列
	 * @return 大文字 に変換された文字列
	 */
	public static String toUpperCase(final String text) {
		return (text == null) ? null : text.toUpperCase();
	}

	/**
	 * チェインケース (ケバブケース) に変換.
	 *
	 * @param word 変換前の文字列
	 * @return チェインケース (ケバブケース) に変換された文字列
	 */
	public static String toChainCase(final String word) {
		return word == null
				? null
				: word.replaceAll("([A-Z])", "-$1").toLowerCase().replaceAll("[-_ ]+", "-").replaceAll("^-|-$", "");
	}

	/**
	 * スネークケース に変換.
	 *
	 * @param word 変換前の文字列
	 * @return スネークケース に変換された文字列
	 */
	public static String toSnakeCase(final String word) {
		return word == null
				? null
				: word.replaceAll("([A-Z])", "_$1").toLowerCase().replaceAll("[_ ]+", "_").replaceAll("^_|_$", "");
	}

	/**
	 * 先頭文字が 小文字 の キャメルケース に変換.
	 *
	 * @param word 変換前の文字列
	 * @return 先頭文字が 小文字 の キャメルケース に変換された文字列
	 */
	public static String toLowerCamelCase(final String word) {
		final String camel = toCamelCase(word);
		if (camel == null || camel.length() < 2) {
			return camel;
		} else {
			return camel.substring(0, 1).toLowerCase() + camel.substring(1);
		}
	}

	/**
	 * 先頭文字が 大文字 の キャメルケース に変換.
	 *
	 * @param word 変換前の文字列
	 * @return 先頭文字が 大文字 の キャメルケース に変換された文字列
	 */
	public static String toUpperCamelCase(final String word) {
		final String camel = toCamelCase(word);
		if (camel == null || camel.length() < 2) {
			return camel;
		} else {
			return camel.substring(0, 1).toUpperCase() + camel.substring(1);
		}
	}

	/**
	 * キャメルケース に変換する プライベート メソッド.
	 *
	 * @param word 変換前の文字列
	 * @return スネークケース に変換された文字列
	 * @see #toUpperCamelCase(String)
	 * @see #toLowerCamelCase(String)
	 */
	private static String toCamelCase(final String word) {
		if (word == null) {
			return null;
		}

		final StringBuilder sb = new StringBuilder();
		final char[] chars = word.toLowerCase().replaceAll("[_ -]+", "_").toCharArray();
		boolean flag = false;
		for (final char c : chars) {
			if (c == '_') {
				flag = true;
				continue;
			}

			if (flag) {
				sb.append(Character.toUpperCase(c));
				flag = false;
			} else {
				sb.append(c);
			}
		}

		return sb.toString();
	}

}

ちなみに、 String.toLowerCase()String.toUpperCase() を使用していますが、 Locale は考慮していませんので、デフォルトの Locale で処理されます。

DEMO プログラム

/**
 * CaseUtils の DEMO.
 *
 * @author https://so-kai-app.sakura.ne.jp/
 */
public final class CaseUtilsDemo {
	/** プライベートコンストラクタ. */
	private CaseUtilsDemo() {
	}

	public static void main(final String args[]) {
		demo("BigBoy");
		demo("Big_____Boy");
		demo("BIGBOY");
		demo("_big_boy_");
		demo(" BIG BOY ");
		demo(" BIG _ BOY ");
		demo("BB");
		demo("B_B");
	}

	private static void demo(final String word) {
		final String format = "\n%20s : [%s]";
		System.out.println("base text = [" + word + "]"
				+ String.format(format, "lower case", CaseUtils.toLowerCase(word))
				+ String.format(format, "UPPER CASE", CaseUtils.toUpperCase(word))
				+ String.format(format, "chain-case", CaseUtils.toChainCase(word))
				+ String.format(format, "snake_case", CaseUtils.toSnakeCase(word))
				+ String.format(format, "LowerCamelCase", CaseUtils.toLowerCamelCase(word))
				+ String.format(format, "UpperCamelCase", CaseUtils.toUpperCamelCase(word)));
	}

}

DEMO 実行結果

base text = [BigBoy]
          lower case : [bigboy]
          UPPER CASE : [BIGBOY]
          chain-case : [big-boy]
          snake_case : [big_boy]
      LowerCamelCase : [bigboy]
      UpperCamelCase : [Bigboy]
base text = [Big_____Boy]
          lower case : [big_____boy]
          UPPER CASE : [BIG_____BOY]
          chain-case : [big-boy]
          snake_case : [big_boy]
      LowerCamelCase : [bigBoy]
      UpperCamelCase : [BigBoy]
base text = [BIGBOY]
          lower case : [bigboy]
          UPPER CASE : [BIGBOY]
          chain-case : [b-i-g-b-o-y]
          snake_case : [b_i_g_b_o_y]
      LowerCamelCase : [bigboy]
      UpperCamelCase : [Bigboy]
base text = [_big_boy_]
          lower case : [_big_boy_]
          UPPER CASE : [_BIG_BOY_]
          chain-case : [big-boy]
          snake_case : [big_boy]
      LowerCamelCase : [bigBoy]
      UpperCamelCase : [BigBoy]
base text = [ BIG BOY ]
          lower case : [ big boy ]
          UPPER CASE : [ BIG BOY ]
          chain-case : [b-i-g-b-o-y]
          snake_case : [b_i_g_b_o_y]
      LowerCamelCase : [bigBoy]
      UpperCamelCase : [BigBoy]
base text = [ BIG _ BOY ]
          lower case : [ big _ boy ]
          UPPER CASE : [ BIG _ BOY ]
          chain-case : [b-i-g-b-o-y]
          snake_case : [b_i_g_b_o_y]
      LowerCamelCase : [bigBoy]
      UpperCamelCase : [BigBoy]
base text = [BB]
          lower case : [bb]
          UPPER CASE : [BB]
          chain-case : [b-b]
          snake_case : [b_b]
      LowerCamelCase : [bb]
      UpperCamelCase : [Bb]
base text = [B_B]
          lower case : [b_b]
          UPPER CASE : [B_B]
          chain-case : [b-b]
          snake_case : [b_b]
      LowerCamelCase : [bB]
      UpperCamelCase : [BB]

プログラムのご利用にあたって

当プログラムは、ご自由に ご利用いただけますが、当プログラムに関連して発生した、いかなる損害に対しても責任を負いません。

ぱっと見た限り問題ないと思うのですが、バグなどがあったら 是非とも お知らせ願います。

宜しくお願い申し上げます。

おしまい。

最後まで お読みいただき、ありがとうございました。

お役に立てたら幸いです。

スポンサーリンク
スポンサーリンク