JavaのMatcherクラスはスレッドセーフ?マルチスレッド利用時の注意点を解説
正規表現とは、特殊な構文で記述されたパターンをもとに、特定の文字列や文字列の集合を照合・検索するための仕組みです。テキストやデータの検索、編集、加工など、さまざまな場面で活用されています。Javaでは、java.util.regex パッケージによって正規表現によるパターンマッチング機能が提供されています。
Matcherクラスとは
Matcherオブジェクトは、パターンを解釈し、入力文字列に対してマッチング操作を実行する「エンジン」の役割を担うクラスです。Patternクラスと同様に、Matcherクラスには公開されたコンストラクタは用意されておらず、Patternオブジェクトの matcher() メソッドを呼び出すことで取得します。
このクラスのインスタンスは、複数のスレッドから同時に使用することはできません(スレッドセーフではありません)。
つまり、複数のスレッドで同じMatcherインスタンスを共有すると、予期しない動作や誤ったマッチング結果を招く恐れがあります。マルチスレッド環境で正規表現を使用する場合は、次のいずれかの対策が必要です。
- 各スレッドごとに個別のMatcherオブジェクトを生成して使用する
- どうしても共有したい場合は、同期(synchronized)処理で排他制御を行う
一方で、Patternクラス自体は不変(イミュータブル)であり、スレッドセーフであることが保証されています。そのため、Patternオブジェクトは複数のスレッド間で安全に共有でき、Matcherだけをスレッドごとに作り直すのが一般的な設計手法です。
サンプルプログラム
次のJavaプログラムは、ユーザーから5つの文字列を入力として受け取り、その中から数字で始まる文字列だけを出力する例です。
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StartingwithDigit {
public static void main( String args[] ) {
String regex = "^[0-9].*$";
Scanner sc = new Scanner(System.in);
System.out.println("Enter 5 input strings: ");
String input[] = new String[5];
for (int i=0; i<5; i++) {
input[i] = sc.nextLine();
}
// Patternオブジェクトの生成
Pattern p = Pattern.compile(regex);
System.out.println("Strings starting with digits: ");
for(int i=0; i<5;i++) {
// Matcherオブジェクトの生成
Matcher m = p.matcher(input[i]);
if(m.matches()) {
System.out.println(m.group());
}
}
}
}
実行結果
Enter 5 input strings: sample string 1 sample string 2 11 sample string 3 22 sample string 4 43534 56353 636 Strings starting with digits: 11 sample string 3 22 sample string 4 43534 56353 636
このように、ループ内で毎回新しいMatcherオブジェクトを生成しているため、単一スレッドでは問題なく動作します。ただし、このMatcherインスタンスを複数スレッドで使い回すことは避け、必要に応じてスレッドごとに生成するようにしましょう。
-
Javaの正規表現を使って文字列からHTMLタグを抽出する方法
Javaのjava.util.regexパッケージには、文字シーケンスの中から特定のパターンを検索するためのさまざまなクラスが用意されています。 このパッケージのPatternクラスは、正規表現をコンパイルした結果を表すクラスです。文字列と正規表現のマッチングを行うために、次の2つのメソッドが提供されています。 compile() − 正規表現を表す文字列を引数として受け取り、Patternクラスのオブジェクトを返します。 matcher() − 対象となる文字列を受け取り、その文字列を現在のPatternオブジェクトが表すパターンと照合するためのMatcherオブジェクトを生成します。
-
Javaの正規表現で文字列から数値を抽出する方法
Javaの正規表現(Regular Expression)を使えば、文字列の中から数値だけを簡単に取り出すことができます。この記事では、実際のコード例とともに、さまざまなパターンでの数値抽出の方法を解説します。文字列を解析し、必要な情報を抜き出すスキルは、テスターにとって欠かせない能力の一つです。特にAPIテストでは、JSONやXML形式のレスポンスを解析する場面が多く、正規表現の知識が大いに役立ちます。以下では、Javaの正規表現を使って文字列から数字・数値を抽出する具体的な例を紹介します。文字列からすべての数値を抽出するimport java.util.regex.Matcher; imp