Find correct next match after matchAt and matchEntire KT-47676

This commit is contained in:
Ilya Gorbunov
2021-07-09 03:43:57 +03:00
committed by teamcityserver
parent 28a0698463
commit 455fee29e4
2 changed files with 33 additions and 10 deletions
+16 -10
View File
@@ -58,6 +58,15 @@ public actual class Regex actual constructor(pattern: String, options: Set<Regex
private fun initStickyPattern(): RegExp =
nativeStickyPattern ?: RegExp(pattern, options.toFlags("yu")).also { nativeStickyPattern = it }
private var nativeMatchesEntirePattern: RegExp? = null
private fun initMatchesEntirePattern(): RegExp =
nativeMatchesEntirePattern ?: run {
if (pattern.startsWith('^') && pattern.endsWith('$'))
nativePattern
else
return RegExp("^${pattern.trimStart('^').trimEnd('$')}$", options.toFlags("gu"))
}.also { nativeMatchesEntirePattern = it }
/** Indicates whether the regular expression matches the entire [input]. */
public actual infix fun matches(input: CharSequence): Boolean {
@@ -96,7 +105,7 @@ public actual class Regex actual constructor(pattern: String, options: Set<Regex
if (startIndex < 0 || startIndex > input.length) {
throw IndexOutOfBoundsException("Start index out of bounds: $startIndex, input length: ${input.length}")
}
return nativePattern.findNext(input.toString(), startIndex)
return nativePattern.findNext(input.toString(), startIndex, nativePattern)
}
/**
@@ -119,12 +128,8 @@ public actual class Regex actual constructor(pattern: String, options: Set<Regex
*
* @return An instance of [MatchResult] if the entire input matches or `null` otherwise.
*/
public actual fun matchEntire(input: CharSequence): MatchResult? {
if (pattern.startsWith('^') && pattern.endsWith('$'))
return find(input)
else
return Regex("^${pattern.trimStart('^').trimEnd('$')}$", options).find(input)
}
public actual fun matchEntire(input: CharSequence): MatchResult? =
initMatchesEntirePattern().findNext(input.toString(), 0, nativePattern)
@SinceKotlin("1.5")
@ExperimentalStdlibApi
@@ -132,7 +137,7 @@ public actual class Regex actual constructor(pattern: String, options: Set<Regex
if (index < 0 || index > input.length) {
throw IndexOutOfBoundsException("index out of bounds: $index, input length: ${input.length}")
}
return initStickyPattern().findNext(input.toString(), index)
return initStickyPattern().findNext(input.toString(), index, nativePattern)
}
@@ -247,7 +252,7 @@ public fun Regex_1(pattern: String): Regex = Regex(pattern, emptySet())
private fun RegExp.findNext(input: String, from: Int): MatchResult? {
private fun RegExp.findNext(input: String, from: Int, nextPattern: RegExp): MatchResult? {
this.lastIndex = from
val match = exec(input)
if (match == null) return null
@@ -278,6 +283,7 @@ private fun RegExp.findNext(input: String, from: Int): MatchResult? {
return groupValues_!!
}
override fun next(): MatchResult? = this@findNext.findNext(input, if (range.isEmpty()) range.start + 1 else range.endInclusive + 1)
override fun next(): MatchResult? =
nextPattern.findNext(input, if (range.isEmpty()) range.start + 1 else range.endInclusive + 1, nextPattern)
}
}