正規表現の一致数をカウントする方法は?
1. 概要
正規表現は、単語カウントアルゴリズムやテキスト入力の検証など、さまざまなテキスト処理タスクに使用できます。
このチュートリアルでは、正規表現を使用して一部のテキストの一致数をカウントする方法を見ていきます。
2. 使用事例
有効な電子メールが文字列に出現する回数をカウントできるアルゴリズムを開発しましょう。
メールアドレスを検出するには、単純な正規表現パターンを使用します。
([a-z0-9_.-]+)@([a-z0-9_.-]+[a-z])
有効な電子メールアドレスを照合するための実際の正規表現は非常に複雑であるため、これはデモンストレーションのみを目的とした些細なパターンであることに注意してください。
Pattern オブジェクト内でこの正規表現が必要になるため、次のように使用できます。
Pattern EMAIL_ADDRESS_PATTERN =
Pattern.compile("([a-z0-9_.-]+)@([a-z0-9_.-]+[a-z])");
2つの主要なアプローチを見ていきます。そのうちの1つは、Java9以降の使用に依存しています。
サンプルテキストでは、文字列内の3つの電子メールを検索しようとします。
"You can contact me through [email protected], [email protected], and [email protected]"
3. Java8以前の一致のカウント
まず、Java8以前を使用して一致をカウントする方法を見てみましょう。
一致をカウントする簡単な方法は、Matcherクラスのfindメソッドを反復処理することです。 このメソッドは、パターンに一致する入力シーケンスの次のサブシーケンスを検索しようとします。
Matcher countEmailMatcher = EMAIL_ADDRESS_PATTERN.matcher(TEXT_CONTAINING_EMAIL_ADDRESSES);
int count = 0;
while (countEmailMatcher.find()) {
count++;
}
このアプローチを使用すると、予想どおり3つの一致が見つかります。
assertEquals(3, count);
find メソッドは、一致が見つかるたびに Matcher をリセットしないことに注意してください。前のシーケンスの終わりが一致した後、文字から再開するため、検索は機能しません。重複するメールアドレス。
たとえば、次の例を考えてみましょう。
String OVERLAPPING_EMAIL_ADDRESSES = "Try to contact us at [email protected]@baeldung.com, [email protected].";
Matcher countOverlappingEmailsMatcher = EMAIL_ADDRESS_PATTERN.matcher(OVERLAPPING_EMAIL_ADDRESSES);
int count = 0;
while (countOverlappingEmailsMatcher.find()) {
count++;
}
assertEquals(2, count);
正規表現が指定された文字列で一致を見つけようとすると、最初に一致として「[email protected]」が見つかります。 @の前にドメイン部分がないため、マーカーはリセットされず、2番目の“ @ baeldung.com”は無視されます。 次に、「[email protected]」を2番目の一致と見なします。
上に示したように、重複する電子メールの例では2つの一致しかありません。
4. Java9以降の一致のカウント
ただし、新しいバージョンのJavaを使用できる場合は、Matcherクラスのresultsメソッドを使用できます。 Java 9で追加されたこのメソッドは、一致結果のシーケンシャルストリームを返し、一致をより簡単にカウントできるようにします。
long count = countEmailMatcher.results()
.count();
assertEquals(3, count);
find で見たように、 Matcher は、resultsメソッドからのストリームの処理中にリセットされません。 同様に、 results メソッドも、重複する一致を見つけるためには機能しません。
5. 結論
この短い記事では、正規表現の一致をカウントする方法を学びました。
最初に、findメソッドをwhileループで使用する方法を学びました。 次に、新しいJava 9ストリーミングメソッドを使用すると、より少ないコードでこれを実行できることを確認しました。
いつものように、コードサンプルはGitHubでから入手できます。