Scalaでの正規表現
1. 概要
正規表現は、テキスト処理に非常に役立ちます。 このチュートリアルでは、Scalaの scala.util.matching.Regex クラスの機能と、それを実際に使用する方法について学習します。
2. RegexScalaのクラス
scala.util.matching.Regex は、Javaのjava.util.regexパッケージに基づいています。 非常にクリーンで簡潔なAPIを提供します。 さらに、パターンマッチングを使用すると、Regexクラスの読みやすさが向上します。
Regexオブジェクトを定義する方法は2つあります。 まず、明示的に作成します。
val polishPostalCode = new Regex("([0-9]{2})\\-([0-9]{3})")
次に、 r メソッドを使用します。これは、同じことを行うための標準的なScalaのような方法です。
val polishPostalCode = "([0-9]{2})\\-([0-9]{3})".r
それでは、Regexを使用した正規表現の一般的な使用例を詳しく見ていきましょう。
3. 一致するものを見つける
最も一般的な使用例の1つは、テキストで一致するものを見つけることです。
findFirstIn メソッドを使用できます。このメソッドは、 Option[String]オブジェクトを返します。
val postCode = polishPostalCode.findFirstIn("Warsaw 01-011, Jerusalem Avenue")
assertEquals("01-011", postCode)
または、 findFirstMatchIn を使用して、 Option[Match]を返すこともできます。
val postCodes = polishPostalCode.findFirstMatchIn("Warsaw 01-011, Jerusalem Avenue")
assertEquals(Some("011"), for (m <- postCodes) yield m.group(2))
すべての一致を検索するために、同様の名前のメソッドがあります。MatchIteratorを返すfindAllIn:
val postCodes = polishPostalCode.findAllIn("Warsaw 01-011, Jerusalem Avenue, Cracow 30-059, Mickiewicza Avenue")
.toList
assertEquals(List("01-011", "30-059"), postCodes)
およびIterator[Match]を返す
val postCodes = polishPostalCode.findAllMatchIn("Warsaw 01-011, Jerusalem Avenue, Cracow 30-059, Mickiewicza Avenue")
.toList
val postalDistricts = for (m <- postCodes) yield m.group(1)
assertEquals(List("01", "30"), postalDistricts)
4. 値の抽出
正規表現が一致すると、パターンマッチングを使用したエクストラクタとしてRegexを使用できます。
val timestamp = "([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{3})".r
val description = "11:34:01.411" match {
case timestamp(hour, minutes, _, _) => s"It's $minutes minutes after $hour"
}
assertEquals("It's 34 minutes after 11", description)
デフォルトでは、正規表現は、パターンが「固定」されているかのように動作します。つまり、文字の中央に配置されます ^ $ –「^ pattern $」。ただし、これらは削除できます。 UnanchoredRegex クラスのアンカーなしメソッドを使用した文字:
val timestampUnanchored = timestamp.unanchored
これで、試合の前後に追加のテキストを配置できますが、それでも見つけることができます。
val description = "Timestamp: 11:34:01.411 error appeared" match {
case timestampUnanchored(hour, minutes, _, _) => s"It's $minutes minutes after $hour"
}
assertEquals("It's 34 minutes after 11", description)
5. テキストの置き換え
もう1つの重要な機能は、テキストの置き換えです。 オーバーロードされたreplaceAllInメソッドでそれを達成できます。
val minutes = timestamp.replaceAllIn("11:34:01.311", m => m.group(2))
assertEquals("34", minutes)
また、この関数をパターンマッチングとうまく組み合わせることができます。
val secondsThatDayInTotal = timestamp.replaceAllIn("11:34:01.311", _ match {
case timestamp(hours, minutes, seconds, _) => s"$hours-$minutes"
})
assertEquals("11-34", secondsThatDayInTotal)
6. 結論
このチュートリアルでは、Scalaの標準ライブラリにあるRegexクラスを紹介しました。 これまで見てきたように、これは最も一般的な正規表現のユースケースに役立つ非常に読みやすいAPIを提供します。
いつものように、完全なソースコードはGitHubのにあります。