前方一致は「この文字列で始まっているか」を見るシンプルな判定
前方一致は、
「文字列が、ある決まった文字列で“始まっているか”どうか」を調べるテクニックです。
商品コードが ABC で始まるものだけ抽出したい。
ログの行が ERROR で始まるものだけ拾いたい。
URLが https:// で始まるか確認したい。
こういうときに使うのが前方一致です。
Javaでは String#startsWith が用意されていて、これをユーティリティとして包んでおくと、
業務コードがかなり読みやすくなります。
基本形:startsWith をそのままラップする
一番シンプルな前方一致ユーティリティ
まずは、Java標準の startsWith をそのまま使う形からいきます。
public final class PrefixMatcher {
private PrefixMatcher() {}
public static boolean startsWith(String text, String prefix) {
if (text == null || prefix == null) {
return false;
}
return text.startsWith(prefix);
}
}
Java使い方はこんな感じです。
System.out.println(PrefixMatcher.startsWith("ABC123", "ABC")); // true
System.out.println(PrefixMatcher.startsWith("XYZ123", "ABC")); // false
System.out.println(PrefixMatcher.startsWith("ERROR: something", "ERROR")); // true
System.out.println(PrefixMatcher.startsWith("INFO: something", "ERROR")); // false
System.out.println(PrefixMatcher.startsWith(null, "ABC")); // false
System.out.println(PrefixMatcher.startsWith("ABC123", null)); // false
Javaここで押さえておきたい重要ポイントは二つです。
一つ目は、「null の扱いをユーティリティ側で決めている」ことです。text か prefix が null のときにどうするかを、
「false を返す」というポリシーで固定しています。
これを決めておくと、呼び出し側で毎回 null チェックを書かなくて済みます。
二つ目は、「業務コードから startsWith の生呼び出しを隠している」ことです。
生で text.startsWith("ABC") をあちこちに書くと、
null チェックの抜けや、大小文字の扱いのバラつきが出やすくなります。
ユーティリティにまとめることで、「前方一致のルール」を一箇所に集約できます。
大文字小文字を無視した前方一致
toLowerCase / toUpperCase で正規化してから比較する
英字を扱うときに必ず出てくるのが「大文字小文字を区別するかどうか」です。
例えば、ログの行が error でも ERROR でも Error でも、
全部「エラー行」として扱いたい、というケースはよくあります。
その場合は、両方を同じ大文字・小文字に揃えてから startsWith します。
public static boolean startsWithIgnoreCase(String text, String prefix) {
if (text == null || prefix == null) {
return false;
}
String t = text.toLowerCase();
String p = prefix.toLowerCase();
return t.startsWith(p);
}
Java使い方はこうです。
System.out.println(
PrefixMatcher.startsWithIgnoreCase("ERROR: something", "error")
); // true
System.out.println(
PrefixMatcher.startsWithIgnoreCase("Error: something", "ERROR")
); // true
System.out.println(
PrefixMatcher.startsWithIgnoreCase("INFO: ok", "error")
); // false
Javaここで深掘りしたい重要ポイントは、「正規化(normalize)してから判定する」という考え方です。
やっていることはシンプルで、
文字列全体を小文字に変換する
プレフィックスも小文字に変換する
そのうえで startsWith する
というだけです。
この「前処理(正規化)+本処理(前方一致)」という分け方は、
部分一致・完全一致・検索など、文字列処理全般でとても重要なパターンです。
「何を無視して、何を区別するか」を前処理で決めてしまうと、
本処理のコードがスッキリします。
前後の空白や全角スペースをどう扱うか
「見た目としてそのプレフィックスで始まっていればOK」にしたい場合
ユーザー入力や外部データでは、
先頭に空白(半角・全角)が紛れ込むことがよくあります。
例えば、" ERROR: something"(先頭に空白)というログ行も、
「ERROR で始まっている」とみなしたいことがあります。
その場合は、前方一致の前に「空白を取り除く」正規化を挟みます。
public static boolean startsWithTrimmed(String text, String prefix) {
if (text == null || prefix == null) {
return false;
}
String t = text.strip(); // 前後の空白(全角スペースも含む)を削除(Java 11以降)
String p = prefix.strip();
return t.startsWith(p);
}
JavaSystem.out.println(
PrefixMatcher.startsWithTrimmed(" ERROR: something", "ERROR")
); // true
System.out.println(
PrefixMatcher.startsWithTrimmed(" ERROR: something", "ERROR")
); // true(全角スペースも削除される)
Javaここでのポイントは、「どこまで正規化するかは要件次第」ということです。
前後の空白だけを無視するのか、
タブや改行も無視するのか、
全角・半角の違いも吸収するのか。
全部を一気にやろうとすると複雑になるので、
まずは「前後の空白を削る」「大文字小文字を揃える」くらいから始めて、
必要に応じて正規化の範囲を広げていくのが現実的です。
実務での前方一致の使いどころ
コード例:ログレベル判定ユーティリティ
前方一致は、業務コードの中で「条件分岐の軸」としてよく使われます。
例えば、ログの1行からログレベルを判定するユーティリティを考えてみましょう。
public enum LogLevel {
ERROR, WARN, INFO, DEBUG, UNKNOWN
}
public final class LogLevelDetector {
private LogLevelDetector() {}
public static LogLevel detect(String logLine) {
if (logLine == null || logLine.isBlank()) {
return LogLevel.UNKNOWN;
}
String line = logLine.strip(); // 前後の空白を削る
if (line.startsWith("ERROR")) {
return LogLevel.ERROR;
}
if (line.startsWith("WARN")) {
return LogLevel.WARN;
}
if (line.startsWith("INFO")) {
return LogLevel.INFO;
}
if (line.startsWith("DEBUG")) {
return LogLevel.DEBUG;
}
return LogLevel.UNKNOWN;
}
}
Java使い方はこうです。
System.out.println(LogLevelDetector.detect("ERROR: something")); // ERROR
System.out.println(LogLevelDetector.detect("WARN: something")); // WARN
System.out.println(LogLevelDetector.detect("INFO: ok")); // INFO
System.out.println(LogLevelDetector.detect("DEBUG: detail")); // DEBUG
System.out.println(LogLevelDetector.detect("TRACE: detail")); // UNKNOWN
Javaここでの重要ポイントは、「前方一致を“意味のある分類”に使っている」ことです。
単に true/false を返すだけでなく、
「どのログレベルか」というビジネス的な意味に変換しています。
こうやって、「低レベルな文字列操作(startsWith)」を
「高レベルなドメインの概念(LogLevel)」に橋渡しするのが、
実務ユーティリティの本当の価値です。
まとめ:前方一致ユーティリティで身につけたい感覚
前方一致は、「この文字列が、指定した文字列で始まっているか」を見る、
とてもシンプルなテクニックです。
まずは
startsWith をそのままラップした基本版
大文字小文字を無視する startsWithIgnoreCase
前後の空白を削ってから判定する startsWithTrimmed
といったユーティリティを用意して、
「null の扱い」「正規化の方針」を自分のプロジェクト内で統一してみてください。
もしあなたのコードのどこかに、
if (line.startsWith("ERROR")) { ... }
Javaのような生の条件が散らばっているなら、
それを PrefixMatcher や LogLevelDetector のようなユーティリティに一度集約してみるといいです。
その小さな整理が、
「読みやすくて変更に強い文字列処理」を書けるエンジニアへの、確かな一歩になります。
