Kotlinで正規表現を使用する

鼻間違ったで正規表現(Regex)を使用する方法について紹介します。鼻偽のRegexは、Javaを含む他の言語と非常に似ています。正規表現の基本的な知識を知っていることを前提サンプルコードを紹介します。

1. Regex

鼻間違ったで正規表現PatternはRegexクラスで管理されます。 以下のようにRegexオブジェクトを作成するときのパターンを引数として渡して、文字列がそのパターンと一致することを確認できます。

fun main(args: Array<String>) {

    val str = "Welcome to codechacha"
    val regex = Regex(".*code")

    val result = regex.containsMatchIn(str)
    println("containsMatchIn: $result")
}

Output:

containsMatchIn: true

"。"は文字0個以上を意味します。したがって、パターン ". code"は、codeで終わる文字列と一致します。パターン ".* code.*"は、codeという文字の両側に0個以上の文字が存在する文字列と一致します。

1.1 Regexオブジェクトの作成方法

Regexオブジェクトは

  1. Regexコンストラクタにパターンを引数として渡して生成

2.パターンが入力された文字列オブジェクトの toRegex()メソッドで生成 することができます。

val regex1 = Regex(".*code")

val regex2 = ".*code".toRegex()

1.2 Regex Option

Regexのコンストラクタは Regex(pattern, option)のように二番目の引数にOptionを引数として受け取ります。

次のようにOptionが適用されたRegexオブジェクトを作成することができます。 RegexOption.IGNORE_CASEは、大文字と小文字を区別せずにパターンを検査します。

fun main(args: Array<String>) {
    val str = "Welcome to codechacha"

    val regex1 = Regex(".*code")
    val regex2 = Regex(".*CODE")
    val regex3 = Regex(".*CODE", RegexOption.IGNORE_CASE)

    println("match(regex1): ${regex1.containsMatchIn(str)}")
    println("match(regex2): ${regex2.containsMatchIn(str)}")
    println("match(regex3): ${regex3.containsMatchIn(str)}")
}

Output:

match(regex1): true
match(regex2): false
match(regex3): true

さらに、様々なRegexOptionはKotlinlang - RegexOptionで確認することができます。

1.3正規表現パターン

鼻偽の正規表現で使用されるパターンは、Javaや他の言語と同じです。 正規表現の意味についてよくわからない場合は、Java - 正規表現(regex)、様々な例として簡単に理解するを参照してください。

2.部分パターンマッチング、全体パターンマッチング

次の二つの関数は、パターンマッチングの結果をboolean型で返します。

  • Regex.containsMatchIn():部分的にパターンが一致する場合、trueを返します
  • Regex.matches():すべてのパターンが一致する場合、trueを返します
fun main(args: Array<String>) {
    val str = "Welcome to codechacha"

    val regex1 = Regex(".*code")
    val regex2 = Regex(".*code.*")

    println("regex1(partial match): ${regex1.containsMatchIn(str)}")
    println("regex1(total match): ${regex1.matches(str)}")

    println("regex2(partial match): ${regex2.containsMatchIn(str)}")
    println("regex2(total match): ${regex2.matches(str)}")
}

Output:

regex1(partial match): true
regex1(total match): false
regex2(partial match): true
regex2(total match): true

3.1 全パターンマッチングと一致する文字列

Regex.matchEntire()は、文字列とパターンが一致するか検査し、その結果をMatchResultオブジェクトで返します。パターンが一致しない場合、nullが返されます。

MatchResultは一致するかどうかだけをboolean型で返すことがありません。以下のように一致する文字列の詳細情報を提供しています。

  • MatchResult.value:一致する文字列です
  • MatchResult.groupValues:グループと一致する文字列に対するリストです
  • MatchResult.groupValues [index] .value:特定のグループのIndexを入力して一致するvalueにアクセスすることができます。 Index 0はパターン全体に一致する文字列です。 Index 1は最初のグループに一致する文字列です
fun main(args: Array<String>) {
    val str = "abcd"
    val regex = Regex("abc([de]+)")

    val matchResult: MatchResult? = regex.matchEntire(str)
    println("match value: ${matchResult?.value}")
    println("match groupValues: ${matchResult?.groupValues}")
    println("match group[1].value: ${matchResult!!.groups[1]!!.value}")
}

Output:

match value: abcd
match groupValues: [abcd, d]
match group[1].value: d

3.2 部分パターンマッチングと一致する文字列

Regex.find()は、文字列とパターンが完全に一致していない場合は、部分的にしか一致する文字列を検索します。一致する文字列があれば、MatchResultを返し、そうでない場合はnullを返します。

fun main(args: Array<String>) {
    val str = "abcda"
    val regex = Regex("abc[de]+")

    val matchResult: MatchResult? = regex.find(str)
    println("match value: ${matchResult?.value}")
}

Output:

match value: abcd

3.3 グループパターンの例

グループは、 (pattern)形態を意味します。興味のある領域をグループに割り当てることができ、MatchResultはグループと一致する文字列の情報を提供しています。

MatchResult.groupValuesは一致する文字列に関する情報です。

  • index 0:全体のパターンと一致する文字列です
  • index 1:最初のグループ (apple|kiwi)と一致する文字列です
  • index 2:第2グループ (banana|blueberry)と一致する文字列です
fun main(args: Array<String>) {
    val str1 = "apple likes banana"
    val str2 = "kiwi likes blueberry"
    val regex = Regex("(apple|kiwi) likes (banana|blueberry)")

    val matchResult1: MatchResult? = regex.matchEntire(str1)
    println("matchResult1: ${matchResult1?.groupValues}")

    val matchResult2: MatchResult? = regex.matchEntire(str2)
    println("matchResult2: ${matchResult2?.groupValues}")
}

Output:

matchResult1: [apple likes banana, apple, banana]
matchResult2: [kiwi likes blueberry, kiwi, blueberry]

4. 部分的に一致するすべてのパターンを探す

文字列から任意のパターンと部分的に一致するすべての文字列を検索するとき Regex.findAll()関数を使用します。

下のように、文字列内のパターンと部分的に一致する文字列に関する情報を Sequence<MatchResult>に戻します。 Iterationを介してアクセスすることができます。

fun main(args: Array<String>){
    val str = "abcd abce"
    val regex = Regex("abc([de]+)")

    val matchResults: Sequence<MatchResult> = regex.findAll(str)
    matchResults?.forEach {
        println("match value: ${it.value}")
    }
}

Output:

match value: abcd
match value: abce

5. Replace

次の関数は、パターンに一致する文字列を別の文字列に置き換えます。

  • replace():パターンに一致するすべての文字列を比較
  • replaceFirst():パターンに一致する最初の文字列だけを交換
fun main(args: Array<String>) {
    val str = "abcda abcef"
    val regex = Regex("abc([de]+)")

    val replaceAll = regex.replace(str, "ABC")
    println(replaceAll)

    val replaceFirst = regex.replaceFirst(str, "ABC")
    println(replaceFirst)
}

Output:

ABCa ABCf
ABCa abcef

6. Split

Regex.split()は、パターンと一致する文字列を基準に分離してリストに戻ります。

fun main(args: Array<String>) {
    val str = "a b c d e f"
    val regex = Regex("\\s")

    val splitList = regex.split(str)
    println(splitList)
}

Output:

[a, b, c, d, e, f]

References

codechachaCopyright ©2019 codechacha