Java substringの使い方を徹底解説|境界仕様・indexOf併用・安全な切り出し
CONTENTS
Javaを用いた開発において、文字列操作の中でも substring による部分文字列の切り出しは、最も頻繁に使用される処理の一つです。
しかし、一見単純そうに見えるこのメソッドですが、
実務では「境界位置の指定ミス」による例外や、「想定よりも1文字足りない」といったバグが発生しやすく、初心者からベテランまで多くのエンジニアがつまずくポイントでもあります。
特に、beginIndex と endIndex の仕様、indexOf との正しい組み合わせ方、そして可読性を損なわない書き方を理解していないと、本番環境でのシステム停止など重大なトラブルに直結してしまいます。
本記事では、substring の基本から実務で役立つ応用パターンまでを体系的に整理します。
文字列操作はJavaプログラミングの土台となる概念ですので、ここを正しく理解し、ログ解析やAPIレスポンス処理などで確実に役立つスキルを身につけましょう。
substringの基本と仕組み|引数のルールを完全理解する
substring は、その名の通り「文字列(String)の一部(sub)を取り出して、新しい文字列として返す」メソッドです。
Javaでは主に以下の2種類の構文が用意されています。
// 1. 開始位置のみ指定(末尾まで取得)
String s1 = text.substring(beginIndex);
// 2. 開始位置と終了位置を指定
String s2 = text.substring(beginIndex, endIndex);
ここで多くの初学者が混乱するのが、「終了位置(endIndex)は文字そのものを含まない」というJava特有のルールです。
beginIndexとendIndexの境界仕様
substring を使いこなすための最重要ポイントは、以下の「半開区間」の仕様を暗記することです。
- beginIndex:含まれる(Start Inclusive)
- endIndex:含まれない(End Exclusive / その直前まで)
例えば、次のコードを見てみましょう。
String text = "ABCDEFG";
// 0番目(A)から、3番目(D)の手前まで
String result = text.substring(0, 3);
System.out.println(result); // 出力: "ABC"
この場合、「0番目から3文字分を取得する」と解釈すると分かりやすいでしょう。
endIndex - beginIndex の計算結果が、取得される文字数(この場合は 3 - 0 = 3文字)と一致するため、文字数の計算ミスを防ぐことができます。
実務で頻発するエラーと例外回避のテクニック
substring は非常に便利な反面、間違ったインデックスを指定すると即座に IndexOutOfBoundsException(範囲外例外)が発生し、プログラムがクラッシュします。
具体的には、以下の3つのケースで例外が発生します。
beginIndexが負の数である場合endIndexが文字列の長さ(length())を超えている場合beginIndexがendIndexよりも大きい場合
例えば、次のようなコードはコンパイルは通りますが、実行時にエラーとなります。
String text = "Java"; // 長さは4
// エラー:開始位置が終了位置より後ろにある
text.substring(3, 1);
// エラー:終了位置5は存在しない(最大インデックスは3)
text.substring(0, 5);
したがって、実務で外部からの入力値(ユーザー入力やファイル読み込みなど)を扱う場合は、必ず事前に長さチェックを行うのが鉄則です。
if (text != null && text.length() >= 5) {
System.out.println(text.substring(0, 5));
} else {
System.out.println("文字列が短すぎます");
}
詳しい仕様については、Java公式ドキュメントのsubstringメソッド解説も併せて参照してください。
条件別で使い分けるsubstringの実践パターン
substring は単体で使うだけでなく、検索メソッドや条件分岐と組み合わせることで真価を発揮します。
ここでは、開発現場で頻繁に登場する「実践的な切り出しパターン」をいくつか紹介します。
1. indexOfとの併用による動的な切り出し
固定の文字数ではなく、「特定の記号が出てくるまで」切り出したいケースです。
例えば、メールアドレスからユーザー名(@より前)とドメイン(@より後ろ)を分離する場合などに使われます。
String email = "user@example.com";
int pos = email.indexOf("@");
if (pos != -1) {
// 0から@の位置まで(@は含まない)
String user = email.substring(0, pos);
// @の次の文字から末尾まで
String domain = email.substring(pos + 1);
System.out.println("User: " + user); // User: user
System.out.println("Domain: " + domain); // Domain: example.com
}
indexOf は指定した文字が見つからない場合に -1 を返すため、必ず if (pos != -1) のチェックを入れることで、意図しないエラーを防げます。
2. ファイル名の拡張子を取得する
ファイルパスやURLの末尾にある拡張子を取得したい場合、lastIndexOf(後ろから検索)と組み合わせると便利です。
String fileName = "report.v2.pdf";
int lastDot = fileName.lastIndexOf(".");
if (lastDot != -1) {
// ドットの次から末尾までを取得
String extension = fileName.substring(lastDot + 1);
System.out.println(extension); // "pdf"
}
indexOf ではなく lastIndexOf を使うことで、ファイル名の中に複数のドットが含まれていても、正しく最後の拡張子だけを取得できます。
substring と split の使い分け基準
文字列を分割する際、substring のほかに split メソッドを使う方法もあります。
どちらを使うべきか迷った場合は、以下の基準で判断すると良いでしょう。
- substring推奨:特定の位置(インデックス)や、特定の1箇所だけで切り分けたい場合。処理が高速
- split推奨:CSVのように、同じ区切り文字で連続して分割したい場合
ただし、split は内部で正規表現を使用するため、ドット(.)やパイプ(|)などの特殊文字を区切りにする場合はエスケープが必要です。
// 失敗例:ドットは正規表現で「任意の文字」
String[] error = "192.168.1.1".split(".");
// 成功例:バックスラッシュでエスケープ
String[] ipParts = "192.168.1.1".split("\\.");
複雑なログ解析などで高度な抽出が必要な場合は、Patternクラスなどの正規表現ライブラリの使用も検討してください。
まとめ
Javaの substring は非常にシンプルですが、正確な仕様理解なしに使うとバグの温床になります。
最後に、安全に使うためのチェックリストをまとめます。
beginIndexは「含む」、endIndexは「含まない(直前まで)」と理解しているか?- 文字列の長さ(
length())を超えるインデックスを指定していないか? indexOfの結果が-1(見つからない)になる可能性を考慮しているか?nullチェックを行っているか?
「たかが文字列操作」と侮らず、境界値チェックや例外処理を徹底することが、堅牢なアプリケーションを作る第一歩です。
特にログ解析やデータ移行などのバッチ処理では、substring のミス一つで処理が全停止することもあります。
ぜひ本記事のコード例を参考に、実務でも安心して使える実装パターンを身につけてください。
つまずいたら、現役エンジニアと一緒に解決しよう
この記事で扱った【Java】は、独学では細かい仕様で詰まりやすい分野です。さらに理解を深めたい方は、Zerocode Onlineで実務直結の学習を進めてみませんか。
コード添削・詰まり解消を丁寧にサポート。
Java/SQL/Spring Bootを体系的に習得。
現場で刺さる成果物づくりを伴走。
時間と場所を選ばず学べます。