[K/N][stdlib] Fixed lookaround regexes (KT-45932)
This commit is contained in:
@@ -56,6 +56,26 @@ constructor (internal val input: CharSequence,
|
||||
var previousMatch = -1
|
||||
var mode = Regex.Mode.MATCH
|
||||
|
||||
private data class MatchResultState(val groupBounds: IntArray, val consumers: IntArray, val enterCounters: IntArray,
|
||||
val startIndex: Int, val previousMatch: Int)
|
||||
|
||||
private var state: MatchResultState? = null
|
||||
|
||||
internal fun saveState() {
|
||||
state = MatchResultState(groupBounds.copyOf(), consumers.copyOf(), enterCounters.copyOf(), startIndex, previousMatch)
|
||||
}
|
||||
|
||||
internal fun rollbackState(): Boolean {
|
||||
return state?.let {
|
||||
it.groupBounds.copyInto(groupBounds)
|
||||
it.consumers.copyInto(consumers)
|
||||
it.enterCounters.copyInto(enterCounters)
|
||||
startIndex = it.startIndex
|
||||
previousMatch = it.previousMatch
|
||||
true
|
||||
} ?: false
|
||||
}
|
||||
|
||||
// MatchResult interface ===========================================================================================
|
||||
/** The range of indices in the original string where match was captured. */
|
||||
override val range: IntRange
|
||||
|
||||
@@ -25,10 +25,10 @@ package kotlin.text.regex
|
||||
/**
|
||||
* Positive lookahead node.
|
||||
*/
|
||||
internal class PositiveLookAheadSet(children: List<AbstractSet>, fSet: FSet) : AtomicJointSet(children, fSet) {
|
||||
internal class PositiveLookAheadSet(children: List<AbstractSet>, fSet: FSet) : LookAroundSet(children, fSet) {
|
||||
|
||||
/** Returns startIndex+shift, the next position to match */
|
||||
override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int {
|
||||
override fun tryToMatch(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int {
|
||||
children.forEach {
|
||||
val shift = it.matches(startIndex, testString, matchResult)
|
||||
if (shift >= 0) {
|
||||
@@ -39,7 +39,6 @@ internal class PositiveLookAheadSet(children: List<AbstractSet>, fSet: FSet) : A
|
||||
return -1
|
||||
}
|
||||
|
||||
override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true
|
||||
override val name: String
|
||||
get() = "PositiveLookaheadJointSet"
|
||||
}
|
||||
@@ -47,10 +46,10 @@ internal class PositiveLookAheadSet(children: List<AbstractSet>, fSet: FSet) : A
|
||||
/**
|
||||
* Negative look ahead node.
|
||||
*/
|
||||
internal class NegativeLookAheadSet(children: List<AbstractSet>, fSet: FSet) : AtomicJointSet(children, fSet) {
|
||||
internal class NegativeLookAheadSet(children: List<AbstractSet>, fSet: FSet) : LookAroundSet(children, fSet) {
|
||||
|
||||
/** Returns startIndex+shift, the next position to match */
|
||||
override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int {
|
||||
override fun tryToMatch(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int {
|
||||
children.forEach {
|
||||
if (it.matches(startIndex, testString, matchResult) >= 0) {
|
||||
return -1
|
||||
@@ -60,7 +59,6 @@ internal class NegativeLookAheadSet(children: List<AbstractSet>, fSet: FSet) : A
|
||||
return next.matches(startIndex, testString, matchResult)
|
||||
}
|
||||
|
||||
override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true
|
||||
override val name: String
|
||||
get() = "NegativeLookaheadJointSet"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
package kotlin.text.regex
|
||||
|
||||
/**
|
||||
* Abstract class for lookahead and lookbehind nodes.
|
||||
*/
|
||||
internal abstract class LookAroundSet(children: List<AbstractSet>, fSet: FSet) : AtomicJointSet(children, fSet) {
|
||||
protected abstract fun tryToMatch(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int
|
||||
|
||||
/** Returns startIndex+shift, the next position to match */
|
||||
override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int {
|
||||
matchResult.saveState()
|
||||
return tryToMatch(startIndex, testString, matchResult).also { if (it < 0) matchResult.rollbackState() }
|
||||
}
|
||||
|
||||
override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true
|
||||
}
|
||||
@@ -25,11 +25,10 @@ package kotlin.text.regex
|
||||
/**
|
||||
* Positive lookbehind node.
|
||||
*/
|
||||
internal class PositiveLookBehindSet(children: List<AbstractSet>, fSet: FSet) : AtomicJointSet(children, fSet) {
|
||||
internal class PositiveLookBehindSet(children: List<AbstractSet>, fSet: FSet) : LookAroundSet(children, fSet) {
|
||||
|
||||
/** Returns startIndex+shift, the next position to match */
|
||||
override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int {
|
||||
|
||||
override fun tryToMatch(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int {
|
||||
matchResult.setConsumed(groupIndex, startIndex)
|
||||
children.forEach {
|
||||
if (it.findBack(0, startIndex, testString, matchResult) >= 0) {
|
||||
@@ -41,7 +40,6 @@ internal class PositiveLookBehindSet(children: List<AbstractSet>, fSet: FSet) :
|
||||
return -1
|
||||
}
|
||||
|
||||
override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true
|
||||
override val name: String
|
||||
get() = "PositiveBehindJointSet"
|
||||
}
|
||||
@@ -49,10 +47,10 @@ internal class PositiveLookBehindSet(children: List<AbstractSet>, fSet: FSet) :
|
||||
/**
|
||||
* Negative look behind node.
|
||||
*/
|
||||
internal class NegativeLookBehindSet(children: List<AbstractSet>, fSet: FSet) : AtomicJointSet(children, fSet) {
|
||||
internal class NegativeLookBehindSet(children: List<AbstractSet>, fSet: FSet) : LookAroundSet(children, fSet) {
|
||||
|
||||
/** Returns startIndex+shift, the next position to match */
|
||||
override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int {
|
||||
override fun tryToMatch(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int {
|
||||
matchResult.setConsumed(groupIndex, startIndex)
|
||||
|
||||
children.forEach {
|
||||
@@ -65,7 +63,6 @@ internal class NegativeLookBehindSet(children: List<AbstractSet>, fSet: FSet) :
|
||||
return next.matches(startIndex, testString, matchResult)
|
||||
}
|
||||
|
||||
override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true
|
||||
override val name: String
|
||||
get() = "NegativeBehindJointSet"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user