導入
プログラミングの現場でログ解析や入力チェックを行う際、「特定の文字列A」あるいは「特定の文字列B」のどちらかが含まれているか判定したい場面は非常に多いです。Javaでこれらを愚直にif文で書くとコードが冗長になりますが、正規表現の「|(パイプ)」を利用すれば、非常にスマートかつメンテナンス性の高いコードを実現できます。今回は、JavaのPatternクラスとMatcherクラスを活用した、論理和の効率的な使い方を解説します。
基礎知識
正規表現における「|(パイプ)」は「論理和(OR)」を意味するメタキャラクターです。例えば「cat|dog」という正規表現は「cat」または「dog」という文字列にマッチします。
Javaではjava.util.regexパッケージの以下のクラスを使用します。
・Pattern:正規表現をコンパイルして保持するクラス。
・Matcher:コンパイルされたパターンを文字列に対して適用・判定するクラス。
・Named groups(名前付きグループ):マッチした部分を特定の名前で取得できる機能で、複雑な条件分岐の際、可読性を劇的に向上させます。
実装/解決策
論理和「|」を使う際のポイントは、「グループ化」です。「A|B」と記述すると、正規表現全体が「A」か「B」かという判定になります。もし「abc」という文字列の中で「a|b」という条件を適用したい場合、単純に書くと意図しない挙動になることがあるため、`(a|b)c`のように括弧で囲むのがコツです。また、Java 7から導入された「名前付きグループ」を組み合わせれば、どちらにマッチしたかを後から簡単に判別できます。
サンプルプログラム
以下のコードは、入力文字列から「Java」または「Python」のいずれかが含まれているかを判定し、さらにどちらにマッチしたかを名前付きグループで抽出する例です。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexOrExample {
public static void main(String[] args) {
// 名前付きグループ(?<名称>…)を使用して、マッチした対象を判別可能にする
String regex = “(?
Pattern pattern = Pattern.compile(regex);
String input = “I am a Java developer.”;
Matcher matcher = pattern.matcher(input);
// findメソッドでマッチング開始
if (matcher.find()) {
// マッチしたグループ名「language」の内容を取得
String matchedValue = matcher.group(“language”);
System.out.println(“マッチしました: ” + matchedValue);
} else {
System.out.println(“該当する言語は見つかりませんでした。”);
}
}
}
応用・注意点
現場で「|」を使用する際に陥りやすい罠が「優先順位」です。例えば「Apple|Orange Pie」とした場合、「Apple」または「Orange Pie」にマッチしますが、意図せず「Apple Pie」や「Orange Pie」を狙っている場合は「(Apple|Orange) Pie」と括弧でくくる必要があります。
また、正規表現のコンパイルはコストがかかる処理です。ループの中で毎回Pattern.compileを呼ぶとパフォーマンスが著しく低下します。static final変数としてPatternを定義し、再利用することを強く推奨します。名前付きグループはデバッグの効率を格段に上げますので、複雑なバリデーションが必要な際はぜひ活用してください。

コメント