1. 概要

Javaで正規表現を操作する場合、通常、特定のPatternの文字シーケンスを検索する必要があります。 これを容易にするために、Java正規表現APIMatcher クラスを提供します。これを使用して、特定の正規表現をテキストと照合できます。

原則として、ほとんどの場合、Matcherクラスの2つの一般的なメソッドのいずれかを使用する必要があります。

  • 探す()
  • matches()

このクイックチュートリアルでは、簡単な例を使用して、これらの方法の違いについて学習します。

2. find()メソッド

簡単に言うと、find()メソッドは、指定された文字列内の正規表現パターンの出現を検索しようとします。 文字列内に複数のオカレンスが見つかった場合、 find()への最初の呼び出しは最初のオカレンスにジャンプします。 その後、 find()メソッドへの後続の各呼び出しは、次の一致するオカレンスに1つずつ進みます。

提供された文字列「さようなら2019とようこそ2020」で4桁の数字のみを検索するとします。

このために、パターン“ \\ d \\ d \\ d \\ d”を使用します。

@Test
public void whenFindFourDigitWorks_thenCorrect() {
    Pattern stringPattern = Pattern.compile("\\d\\d\\d\\d");
    Matcher m = stringPattern.matcher("goodbye 2019 and welcome 2020");

    assertTrue(m.find());
    assertEquals(8, m.start());
    assertEquals("2019", m.group());
    assertEquals(12, m.end());
    
    assertTrue(m.find());
    assertEquals(25, m.start());
    assertEquals("2020", m.group());
    assertEquals(29, m.end());
    
    assertFalse(m.find());
}

この例では、20192020の2つのオカレンスがあるため、 find()メソッドは true を2回、1回返します。一致領域の終わりに達すると、falseが返されます。

一致するものが見つかったら、 start()、group()、end()などのメソッドを使用して、上記のように、matchに関する詳細を取得できます。

start()メソッドは一致の開始インデックスを提供し、 end()は一致終了後の文字の最後のインデックスを返し、 group( )は、matchの実際の値を返します。

3. find(int)メソッド

また、findメソッドのオーバーロードバージョン— find(int)もあります。 開始インデックスをパラメーターとして受け取り、は開始インデックスを開始点と見なして、文字列内のオカレンスを検索します。

前と同じ例でこのメソッドを使用する方法を見てみましょう。

@Test
public void givenStartIndex_whenFindFourDigitWorks_thenCorrect() {
    Pattern stringPattern = Pattern.compile("\\d\\d\\d\\d");
    Matcher m = stringPattern.matcher("goodbye 2019 and welcome 2020");

    assertTrue(m.find(20));
    assertEquals(25, m.start());
    assertEquals("2020", m.group());
    assertEquals(29, m.end());  
}

の開始インデックスを提供したので 20 、検出されたオカレンスは1つだけであることがわかります— 2020、 これは、このインデックスの後に予想どおりに発生しますそして、の場合のように探す() 、次のような方法を使用できます始める() グループ() 、 と終わり() 試合の詳細を抽出します。

4. matches()メソッド

一方、 the matches()メソッドは、文字列全体をパターンと照合しようとします。

同じ例で、 matches()falseを返します。

@Test
public void whenMatchFourDigitWorks_thenFail() {
    Pattern stringPattern = Pattern.compile("\\d\\d\\d\\d");
    Matcher m = stringPattern.matcher("goodbye 2019 and welcome 2020");
 
    assertFalse(m.matches());
}

これは、「\\ d \\ d \\ d \\ d」を文字列全体「さようなら2019、ようこそ2020」と一致させようとするためです。 find()メソッドとfind(int)メソッド。どちらも、文字列内の任意の場所でパターンの出現を検出します。

文字列を4桁の数字“ 2019” に変更すると、 matches()trueを返します。

@Test
public void whenMatchFourDigitWorks_thenCorrect() {
    Pattern stringPattern = Pattern.compile("\\d\\d\\d\\d");
    Matcher m = stringPattern.matcher("2019");
    
    assertTrue(m.matches());
    assertEquals(0, m.start());
    assertEquals("2019", m.group());
    assertEquals(4, m.end());
    assertTrue(m.matches());
}

上記のように、 start() group() end()などのメソッドを使用して、一致に関する詳細を収集することもできます。 注意すべき興味深い点の1つは、最初の例で見たように、find()を複数回呼び出すと、これらのメソッドを呼び出した後に異なる出力が返される場合がありますが、matches()は常に同じ値を返すことです。

5. matcher() Pattern.matches()の違い

前のセクションで見たように、 matcher()メソッドは、指定された入力をパターンと照合するMatcherを返します。

一方、 Pattern.matches()は正規表現をコンパイルする静的メソッドであり、は入力全体をそれと照合します

違いを強調するためのテストケースを作成しましょう。

@Test
public void whenUsingMatcher_thenReturnTrue() {
    Pattern pattern = Pattern.compile(REGEX);
    Matcher matcher = pattern.matcher(STRING_INPUT);

    assertTrue(matcher.find());
}

つまり、 matcher()を使用する場合、次の質問をします。文字列にパターンが含まれていますか?

そして、 Pattern.matches()を使用して、次のように質問します。文字列はパターンですか?

実際の動作を見てみましょう。

@Test
public void whenUsingMatches_thenReturnFalse() {
    assertFalse(Pattern.matches(REGEX, STRING_INPUT));
}

Pattern.matches()は文字列全体を照合しようとするため、falseを返します。

6. 結論

この記事では、 find() find(int)、および matches()が実際の例でどのように異なるかを見てきました。 また、 start() group() end()などのさまざまなメソッドが、特定の一致に関する詳細を抽出するのにどのように役立つかを見てきました

いつものように、記事の完全なソースコードは、GitHubから入手できます。