サーチ…
式の正規表現マッチングのイディオム
不変のローカルの使用:
「匿名の一時ファイル」テンプレートよりも、水平方向のスペースは少なくなりますが、垂直方向のスペースは大きくなります。 when
式がループ内にある場合は、 "anonymous temporaries"テンプレートよりも優先します。この場合、正規表現の定義はループの外側に配置する必要があります。
import kotlin.text.regex
var string = /* some string */
val regex1 = Regex( /* pattern */ )
val regex2 = Regex( /* pattern */ )
/* etc */
when {
regex1.matches(string) -> /* do stuff */
regex2.matches(string) -> /* do stuff */
/* etc */
}
匿名の一時ファイルを使用する:
「不変のローカル」テンプレートよりも、垂直方向のスペースは少なくなりますが、水平方向のスペースは大きくなります。 expressionがループ内にあるwhen
は使用しないでください。
import kotlin.text.regex
var string = /* some string */
when {
Regex( /* pattern */ ).matches(string) -> /* do stuff */
Regex( /* pattern */ ).matches(string) -> /* do stuff */
/* etc */
}
訪問者パターンの使用:
syntaxのwhen
"引数 - ful"を厳密にエミュレートする利点があります。これは、 when
式の引数をより明確に示し、すべてのwhenEntry
when
引数を繰り返さなければならないことから生じる特定のプログラマー間違いを排除するwhenEntry
です。この実装では、「不変のローカル」テンプレートまたは「匿名の一時的な」テンプレートのいずれかをビジターパターンとして使用することができます。
import kotlin.text.regex
var string = /* some string */
when (RegexWhenArgument(string)) {
Regex( /* pattern */ ) -> /* do stuff */
Regex( /* pattern */ ) -> /* do stuff */
/* etc */
}
when
式引数のラッパークラスの最小定義:
class RegexWhenArgument (val whenArgument: CharSequence) {
operator fun equals(whenEntry: Regex) = whenEntry.matches(whenArgument)
override operator fun equals(whenEntry: Any?) = (whenArgument == whenEntry)
}
Kotlinの正規表現の紹介
この記事では、 Regex
クラスのほとんどの関数の使い方、 Regex
関数に安全に関連したnullをRegex
方法、および生の文字列が正規表現パターンの書き込みと読み込みを容易にする方法を示します。
RegExクラス
Kotlinで正規表現を操作するには、 Regex(pattern: String)
クラスを使用し、その正規表現オブジェクトでfind(..)
やreplace(..)
ような関数を呼び出す必要があります。
input
文字列にcまたはdが含まれている場合にtrueを返すRegex
クラスを使用する方法の例:
val regex = Regex(pattern = "c|d")
val matched = regex.containsMatchIn(input = "abc") // matched: true
すべてのRegex
関数で理解することは、結果が正規表現pattern
とinput
文字列のマッチングに基づいていることです。関数の中には完全一致が必要なものもあれば、部分一致のみが必要なものもあります。この例で使用されているcontainsMatchIn(..)
関数は、部分一致が必要で、この記事の後半で説明します。
正規表現によるNullの安全
find(..)
とmatchEntire(..)
のMatchResult?
オブジェクト。 ?
Kotlinがnullを安全に処理するためには、 MatchResult
後のMatchResult
が必要です。
find(..)
関数がnullを返すとき、KotlinがRegex
関数からnullを安全に処理する方法を示す例:
val matchResult =
Regex("c|d").find("efg") // matchResult: null
val a = matchResult?.value // a: null
val b = matchResult?.value.orEmpty() // b: ""
a?.toUpperCase() // Still needs question mark. => null
b.toUpperCase() // Accesses the function directly. => ""
orEmpty()
関数を使用すると、 b
をnullにすることはできません?
b
関数を呼び出すと、文字は不要です。
あなたがnull値のこの安全な扱いに気にしないなら、KotlinはJavaのようにヌル値で作業することを可能にします!!
文字:
a!!.toUpperCase() // => KotlinNullPointerException
正規表現パターンの生の文字列
Kotlinは、Java 文字列を使ってJava 文字列を改良しています。これにより、Java文字列で必要な、二重バックスラッシュのない純粋な正規表現パターンを書くことができます。生の文字列は三重引用符で表されます:
"""\d{3}-\d{3}-\d{4}""" // raw Kotlin string
"\\d{3}-\\d{3}-\\d{4}" // standard Java string
find(input:CharSequence、startIndex:Int):MatchResult?
input
文字列はRegex
オブジェクトのpattern
と照合されます。 Matchresult?
返しますMatchresult?
startIndex
後に最初に一致するテキストを持つオブジェクト。パターンがinput
文字列と一致しなかった場合はnull
。結果の文字列はMatchResult?
から取得されMatchResult?
オブジェクトのvalue
プロパティ。 startIndex
パラメーターは省略可能で、既定値は0です。
連絡先の詳細を含む文字列から最初の有効な電話番号を抽出するには:
val phoneNumber :String? = Regex(pattern = """\d{3}-\d{3}-\d{4}""")
.find(input = "phone: 123-456-7890, e..")?.value // phoneNumber: 123-456-7890
input
文字列に有効な電話番号がない場合、変数phoneNumber
はnull
になりnull
。
findAll(input:CharSequence、startIndex:Int):シーケンス
正規表現pattern
一致するinput
文字列からすべての一致を返します。
空白で区切られたすべての数字を、文字と数字のあるテキストから印刷するには:
val matchedResults = Regex(pattern = """\d+""").findAll(input = "ab12cd34ef")
val result = StringBuilder()
for (matchedText in matchedResults) {
result.append(matchedText.value + " ")
}
println(result) // => 12 34
matchedResults
変数は、 MatchResult
オブジェクトを持つMatchResult
です。数字なしのinput
文字列では、 findAll(..)
関数は空のシーケンスを返します。
matchEntire(入力:CharSequence):MatchResult?
input
文字列のすべての文字が正規表現pattern
と一致する場合、 input
と等しい文字列が返されます。それ以外の場合は、 null
が返されます。
入力文字列全体が数値の場合、入力文字列を返します。
val a = Regex("""\d+""").matchEntire("100")?.value // a: 100
val b = Regex("""\d+""").matchEntire("100 dollars")?.value // b: null
matches(input:CharSequence):Boolean
入力文字列全体が正規表現パターンと一致する場合に真を返します。そうでなければFalse。
2つの文字列に数字だけが含まれているかどうかをテストします。
val regex = Regex(pattern = """\d+""")
regex.matches(input = "50") // => true
regex.matches(input = "50 dollars") // => false
containsMatchIn(入力:CharSequence):ブール値
入力文字列の一部が正規表現パターンと一致する場合に真を返します。そうでなければFalse。
2つの文字列に少なくとも1つの数字が含まれているかどうかをテストする
Regex("""\d+""").containsMatchIn("50 dollars") // => true
Regex("""\d+""").containsMatchIn("Fifty dollars") // => false
split(入力:CharSequence、limit:Int):リスト
すべての正規表現マッチのない新しいリストを返します。
桁のないリストを返すには:
val a = Regex("""\d+""").split("ab12cd34ef") // a: [ab, cd, ef]
val b = Regex("""\d+""").split("This is a test") // b: [This is a test]
各分割のリストには1つの要素があります。最初のinput
文字列には3つの数字があります。その結果、3つの要素からなるリストが得られます。
置換(入力:CharSequence、置換:String):文字列
input
文字列内の正規表現pattern
すべての一致を置換文字列に置き換えます。
文字列内のすべての数字をx:
val result = Regex("""\d+""").replace("ab12cd34ef", "x") // result: abxcdxef