英字抽出は「ごちゃ混ぜ文字列から“アルファベットだけ”をすくい上げる」技
業務システムでは、「商品名に英字と数字と日本語が混ざっている」「ログにIDやコードが埋まっている」「外部システムから来た文字列がカオス」という状況がよくあります。
そこから「英字だけ欲しい」「英字の塊(コード)だけ欲しい」「文章中のすべての英単語っぽいものを拾いたい」といったニーズが出てきます。
このときに役立つのが「英字抽出」のユーティリティです。
ポイントは、「1文字ずつの英字が欲しいのか」「連続した英字の塊(単語・コード)が欲しいのか」を最初に決めておくことです。
基本の考え方:「連続した英字の塊」を1つの単語・コードとして扱う
正規表現で「英字のかたまり」を見つける
まずは一番よくある、「連続した英字を1つの塊として扱う」パターンからいきます。
例えば、次のような文字列があるとします。
商品コード: ABC123-JP 説明: Premium Coffee 200g
ここから「ABC」「JP」「Premium」「Coffee」を取り出したい、というイメージです。
Java では、正規表現 [A-Za-z]+ を使うと「1文字以上の連続した英字」にマッチできます。
これを Matcher#find() で繰り返し拾っていくのが基本パターンです。
連続した英字をすべて抽出するユーティリティ
文字列中の「英字の塊」を List<String> で返す
まずは、「文字列中に出てくる英字の塊を全部文字列として集める」ユーティリティを作ります。
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class AlphaExtractor {
private static final Pattern ALPHAS = Pattern.compile("[A-Za-z]+");
private AlphaExtractor() {}
public static List<String> extractAllAlphaBlocks(String text) {
List<String> result = new ArrayList<>();
if (text == null || text.isEmpty()) {
return result;
}
Matcher m = ALPHAS.matcher(text);
while (m.find()) {
result.add(m.group());
}
return result;
}
}
Java使い方はこうなります。
String s = "商品コード: ABC123-JP 説明: Premium Coffee 200g";
List<String> alphas = AlphaExtractor.extractAllAlphaBlocks(s);
System.out.println(alphas); // [ABC, JP, Premium, Coffee]
Javaここで深掘りしたい重要ポイントは、「matches() ではなく find() をループしている」ことです。matches() は「文字列全体がパターンに一致するか」を見るのに対し、find() は「文字列の中から、パターンに一致する部分を順番に見つけていく」ためのメソッドです。
英字抽出のように「文章の中から何度も出てくる英字の塊を全部拾いたい」場合は、find() のループが基本形になります。
例題:文章中の「最初の英字の塊だけ」を取りたい
「一番最初に出てくる英字コード」を 1つだけ返す
よくあるのが、「メッセージ中の最初の英字コードだけ欲しい」というパターンです。
例えば、「エラーメッセージからエラーコード(英字)だけ取りたい」といったケースです。
import java.util.regex.Matcher;
public final class AlphaExtractor {
private static final Pattern ALPHAS = Pattern.compile("[A-Za-z]+");
private AlphaExtractor() {}
public static String extractFirstAlphaBlock(String text) {
if (text == null || text.isEmpty()) {
return null;
}
Matcher m = ALPHAS.matcher(text);
if (m.find()) {
return m.group();
}
return null;
}
}
Java使い方はこうです。
String msg = "ERROR_CODE[NET-105] 接続に失敗しました。";
String codePrefix = AlphaExtractor.extractFirstAlphaBlock(msg);
System.out.println(codePrefix); // ERROR
Javaここで深掘りしたいのは、「“最初の1つだけ”という要件をメソッド名と戻り値の型で表現している」ことです。extractAll... は List、extractFirst... は単一値(または null)という形にしておくと、呼び出し側が「このメソッドは何個返してくるのか」を直感的に理解できます。
英字だけを連結して「英字だけの文字列」を作る
「英字以外を全部捨てて、英字だけをつなげたい」
ときどき、「文字列から英字だけを抜き出して、1つの文字列にしたい」というニーズもあります。
例えば、「ABC-123-xyz から ABCxyz だけ欲しい」といったケースです。
これは「英字以外を全部削除する」という発想でも書けますが、
ここでは「英字の塊を全部拾ってから連結する」パターンで書いてみます。
public final class AlphaExtractor {
private static final Pattern ALPHAS = Pattern.compile("[A-Za-z]+");
private AlphaExtractor() {}
public static String extractAllAlphasAsSingleString(String text) {
if (text == null || text.isEmpty()) {
return "";
}
StringBuilder sb = new StringBuilder();
Matcher m = ALPHAS.matcher(text);
while (m.find()) {
sb.append(m.group());
}
return sb.toString();
}
}
Java使い方はこうです。
String s = "ABC-123-xyz_456";
String onlyAlpha = AlphaExtractor.extractAllAlphasAsSingleString(s);
System.out.println(onlyAlpha); // ABCxyz
Javaここでの重要ポイントは、「“英字だけを残す”という要件を、正規表現+ビルダーで明示的に表現している」ことです。text.replaceAll("[^A-Za-z]", "") のように「非英字を全部消す」書き方もありますが、extractAllAlphaBlocks と同じパターンで書いておくと、「どこで何をしているか」が揃って読みやすくなります。
大文字・小文字の扱いをどうするか
「大文字・小文字を区別するか」「揃えるか」を最初に決める
英字抽出では、「大文字と小文字を区別するか」「結果をすべて大文字(または小文字)に揃えるか」という設計も重要です。
例えば、「コードは大文字で扱いたい」という要件なら、抽出後に toUpperCase() をかけるユーティリティを用意しておくと便利です。
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class AlphaExtractor {
private static final Pattern ALPHAS = Pattern.compile("[A-Za-z]+");
private AlphaExtractor() {}
public static List<String> extractAllAlphaBlocksUpper(String text) {
List<String> result = new ArrayList<>();
if (text == null || text.isEmpty()) {
return result;
}
Matcher m = ALPHAS.matcher(text);
while (m.find()) {
result.add(m.group().toUpperCase(Locale.ROOT));
}
return result;
}
}
Java使い方はこうです。
String s = "code: abc123, Region: jp, Owner: Smith";
System.out.println(AlphaExtractor.extractAllAlphaBlocksUpper(s));
// [CODE, ABC, REGION, JP, OWNER, SMITH]
Javaここで深掘りしたいのは、「大文字・小文字の扱いを“呼び出し側の気分”に任せず、ユーティリティのメソッド名と実装で明示する」ことです。extractAllAlphaBlocks はそのまま、extractAllAlphaBlocksUpper は大文字に揃える、といった形で分けておくと、
後から読んだときに「このコードは何を期待しているのか」が一目で分かります。
例題:英字コードだけを抜き出して一覧にする
「ログ中の英字コードを全部拾って分析したい」
例えば、次のようなログが大量にあるとします。
2025-01-30 INFO CODE=NET_ERR_01 message=Connection failed
2025-01-30 INFO CODE=AUTH_WARN_02 message=Password weak
ここから NET_ERR_01 や AUTH_WARN_02 のような「英字+アンダースコア+数字」のコードだけを抜き出したい、というケースです。
この場合は、「英字だけ」ではなく「英字を含む特定フォーマットのコード」を対象にしたほうが実務的です。
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class CodeExtractor {
// 例: NET_ERR_01, AUTH_WARN_02 など
private static final Pattern CODE_PATTERN =
Pattern.compile("[A-Z]+(?:_[A-Z]+)*_\\d+");
private CodeExtractor() {}
public static List<String> extractAllCodes(String text) {
List<String> result = new ArrayList<>();
if (text == null || text.isEmpty()) {
return result;
}
Matcher m = CODE_PATTERN.matcher(text);
while (m.find()) {
result.add(m.group());
}
return result;
}
}
Java使い方はこうです。
String logs = """
2025-01-30 INFO CODE=NET_ERR_01 message=Connection failed
2025-01-30 INFO CODE=AUTH_WARN_02 message=Password weak
""";
System.out.println(CodeExtractor.extractAllCodes(logs));
// [NET_ERR_01, AUTH_WARN_02]
Javaここでの重要ポイントは、「“英字抽出”を土台にしつつ、業務で意味のあるフォーマット(コード)に特化したパターンをユーティリティとして切り出している」ことです。
単に [A-Za-z]+ で全部拾うのではなく、「このプロジェクトで“コード”と呼ぶものはこういう形」というルールを正規表現で固定しておくと、
ログ解析や集計が格段にやりやすくなります。
まとめ:英字抽出ユーティリティで身につけたい感覚
英字抽出は、「文字と数字、日本語や記号が混ざった世界から、“アルファベットとして意味のある部分”だけをすくい上げる」技です。
押さえておきたい感覚は、まず「連続した英字の塊を [A-Za-z]+ で拾い、Matcher#find() のループで全部集める」という基本パターン。
次に、「extractAll... と extractFirst...、...Blocks と ...AsSingleString のように、メソッド名と戻り値の型で“何をどの単位で取りたいのか”をはっきり表現する」こと。
そして、「大文字・小文字の扱いや、“英字を含むコード形式”などの業務ルールをユーティリティに閉じ込め、プロジェクト全体で同じ抽出ロジックを共有する」ことです。
もしあなたのコードのどこかに、text.replaceAll("[^A-Za-z]", "") や text.matches(".*[A-Za-z].*") のような断片的な処理が散らばっているなら、
それを題材にして、ここで作った AlphaExtractor や CodeExtractor のようなユーティリティにまとめてみてください。
それだけで、「読みやすくて、再利用できて、仕様変更にも強い英字抽出」に、一段レベルアップできます。
