Provide overloads both for Strings and CharSequences of removePrefix, removeSuffix, removeSurronding, trim* and pad*, replaceRange & removeRange
This commit is contained in:
@@ -9,9 +9,9 @@ import kotlin.text.MatchResult
|
||||
import kotlin.text.Regex
|
||||
|
||||
/**
|
||||
* Returns a string with leading and trailing characters matching the [predicate] trimmed.
|
||||
* Returns a sub sequence of this char sequence having leading and trailing characters matching the [predicate] trimmed.
|
||||
*/
|
||||
inline public fun CharSequence.trim(predicate: (Char) -> Boolean): String {
|
||||
inline public fun CharSequence.trim(predicate: (Char) -> Boolean): CharSequence {
|
||||
var startIndex = 0
|
||||
var endIndex = length() - 1
|
||||
var startFound = false
|
||||
@@ -34,24 +34,36 @@ inline public fun CharSequence.trim(predicate: (Char) -> Boolean): String {
|
||||
}
|
||||
}
|
||||
|
||||
return substring(startIndex, endIndex + 1)
|
||||
return subSequence(startIndex, endIndex + 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string with leading characters matching the [predicate] trimmed.
|
||||
* Returns a string with leading and trailing characters matching the [predicate] trimmed.
|
||||
*/
|
||||
inline public fun CharSequence.trimStart(predicate: (Char) -> Boolean): String {
|
||||
inline public fun String.trim(predicate: (Char) -> Boolean): String
|
||||
= (this as CharSequence).trim(predicate).toString()
|
||||
|
||||
/**
|
||||
* Returns a sub sequence of this char sequence having leading characters matching the [predicate] trimmed.
|
||||
*/
|
||||
inline public fun CharSequence.trimStart(predicate: (Char) -> Boolean): CharSequence {
|
||||
for (index in this.indices)
|
||||
if (!predicate(this[index]))
|
||||
return substring(index)
|
||||
return subSequence(index, length)
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string with trailing characters matching the [predicate] trimmed.
|
||||
* Returns a string with leading characters matching the [predicate] trimmed.
|
||||
*/
|
||||
inline public fun CharSequence.trimEnd(predicate: (Char) -> Boolean): String {
|
||||
inline public fun String.trimStart(predicate: (Char) -> Boolean): String
|
||||
= (this as CharSequence).trimStart(predicate).toString()
|
||||
|
||||
/**
|
||||
* Returns a sub sequence of this char sequence having trailing characters matching the [predicate] trimmed.
|
||||
*/
|
||||
inline public fun CharSequence.trimEnd(predicate: (Char) -> Boolean): CharSequence {
|
||||
for (index in this.indices.reversed())
|
||||
if (!predicate(this[index]))
|
||||
return substring(0, index + 1)
|
||||
@@ -60,77 +72,137 @@ inline public fun CharSequence.trimEnd(predicate: (Char) -> Boolean): String {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string with leading and trailing characters in the [chars] array trimmed.
|
||||
* Returns a string with trailing characters matching the [predicate] trimmed.
|
||||
*/
|
||||
public fun CharSequence.trim(vararg chars: Char): String = trim { it in chars }
|
||||
inline public fun String.trimEnd(predicate: (Char) -> Boolean): String
|
||||
= (this as CharSequence).trimEnd(predicate).toString()
|
||||
|
||||
/**
|
||||
* Returns a string with leading and trailing characters in the [chars] array trimmed.
|
||||
* Returns a sub sequence of this char sequence having leading and trailing characters from the [chars] array trimmed.
|
||||
*/
|
||||
public fun CharSequence.trimStart(vararg chars: Char): String = trimStart { it in chars }
|
||||
public fun CharSequence.trim(vararg chars: Char): CharSequence = trim { it in chars }
|
||||
|
||||
/**
|
||||
* Returns a string with trailing characters in the [chars] array trimmed.
|
||||
* Returns a string with leading and trailing characters from the [chars] array trimmed.
|
||||
*/
|
||||
public fun CharSequence.trimEnd(vararg chars: Char): String = trimEnd { it in chars }
|
||||
public fun String.trim(vararg chars: Char): String = trim { it in chars }
|
||||
|
||||
/**
|
||||
* Returns a sub sequence of this char sequence having leading and trailing characters from the [chars] array trimmed.
|
||||
*/
|
||||
public fun CharSequence.trimStart(vararg chars: Char): CharSequence = trimStart { it in chars }
|
||||
|
||||
/**
|
||||
* Returns a string with leading and trailing characters from the [chars] array trimmed.
|
||||
*/
|
||||
public fun String.trimStart(vararg chars: Char): String = trimStart { it in chars }
|
||||
|
||||
/**
|
||||
* Returns a sub sequence of this char sequence having trailing characters from the [chars] array trimmed.
|
||||
*/
|
||||
public fun CharSequence.trimEnd(vararg chars: Char): CharSequence = trimEnd { it in chars }
|
||||
|
||||
/**
|
||||
* Returns a string with trailing characters from the [chars] array trimmed.
|
||||
*/
|
||||
public fun String.trimEnd(vararg chars: Char): String = trimEnd { it in chars }
|
||||
|
||||
/**
|
||||
* Returns a sub sequence of this char sequence having leading and trailing whitespace trimmed.
|
||||
*/
|
||||
public fun CharSequence.trim(): CharSequence = trim { it.isWhitespace() }
|
||||
|
||||
/**
|
||||
* Returns a string with leading and trailing whitespace trimmed.
|
||||
*/
|
||||
public fun CharSequence.trim(): String = trim { it.isWhitespace() }
|
||||
public fun String.trim(): String = (this as CharSequence).trim().toString()
|
||||
|
||||
/**
|
||||
* Returns a sub sequence of this char sequence having leading whitespace removed.
|
||||
*/
|
||||
public fun CharSequence.trimStart(): CharSequence = trimStart { it.isWhitespace() }
|
||||
|
||||
/**
|
||||
* Returns a string with leading whitespace removed.
|
||||
*/
|
||||
public fun CharSequence.trimStart(): String = trimStart { it.isWhitespace() }
|
||||
public fun String.trimStart(): String = (this as CharSequence).trimStart().toString()
|
||||
|
||||
/**
|
||||
* Returns a sub sequence of this char sequence having trailing whitespace removed.
|
||||
*/
|
||||
public fun CharSequence.trimEnd(): CharSequence = trimEnd { it.isWhitespace() }
|
||||
|
||||
/**
|
||||
* Returns a string with trailing whitespace removed.
|
||||
*/
|
||||
public fun CharSequence.trimEnd(): String = trimEnd { it.isWhitespace() }
|
||||
public fun String.trimEnd(): String = (this as CharSequence).trimEnd().toString()
|
||||
|
||||
/**
|
||||
* Left pad a String with a specified character or space.
|
||||
* Returns a char sequence with content of this char sequence padded at the beginning
|
||||
* to the specified [length] with the specified character or space.
|
||||
*
|
||||
* @param length the desired string length.
|
||||
* @param padChar the character to pad string with, if it has length less than the [length] specified. Space is used by default.
|
||||
* @returns Returns a string, of length at least [length], consisting of string prepended with [padChar] as many times.
|
||||
* as are necessary to reach that length.
|
||||
*/
|
||||
public fun CharSequence.padStart(length: Int, padChar: Char = ' '): String {
|
||||
public fun CharSequence.padStart(length: Int, padChar: Char = ' '): CharSequence {
|
||||
if (length < 0)
|
||||
throw IllegalArgumentException("String length $length is less than zero.")
|
||||
if (length <= this.length())
|
||||
return this.toString()
|
||||
throw IllegalArgumentException("Desired length $length is less than zero.")
|
||||
if (length <= this.length)
|
||||
return this.subSequence(0, this.length)
|
||||
|
||||
val sb = StringBuilder(length)
|
||||
for (i in 1..(length - this.length()))
|
||||
for (i in 1..(length - this.length))
|
||||
sb.append(padChar)
|
||||
sb.append(this)
|
||||
return sb.toString()
|
||||
return sb
|
||||
}
|
||||
|
||||
/**
|
||||
* Right pad a String with a specified character or space.
|
||||
* Pads the string to the specified [length] at the beginning with the specified character or space.
|
||||
*
|
||||
* @param length the desired string length.
|
||||
* @param padChar the character to pad string with, if it has length less than the [length] specified. Space is used by default.
|
||||
* @returns Returns a string, of length at least [length], consisting of string prepended with [padChar] as many times.
|
||||
* as are necessary to reach that length.
|
||||
*/
|
||||
public fun CharSequence.padEnd(length: Int, padChar: Char = ' '): String {
|
||||
public fun String.padStart(length: Int, padChar: Char = ' '): String
|
||||
= (this as CharSequence).padStart(length, padChar).toString()
|
||||
|
||||
/**
|
||||
* Returns a char sequence with content of this char sequence padded at the end
|
||||
* to the specified [length] with the specified character or space.
|
||||
*
|
||||
* @param length the desired string length.
|
||||
* @param padChar the character to pad string with, if it has length less than the [length] specified. Space is used by default.
|
||||
* @returns Returns a string, of length at least [length], consisting of string prepended with [padChar] as many times.
|
||||
* as are necessary to reach that length.
|
||||
*/
|
||||
public fun CharSequence.padEnd(length: Int, padChar: Char = ' '): CharSequence {
|
||||
if (length < 0)
|
||||
throw IllegalArgumentException("String length $length is less than zero.")
|
||||
if (length <= this.length())
|
||||
return this.toString()
|
||||
throw IllegalArgumentException("Desired length $length is less than zero.")
|
||||
if (length <= this.length)
|
||||
return this.subSequence(0, this.length)
|
||||
|
||||
val sb = StringBuilder(length)
|
||||
sb.append(this)
|
||||
for (i in 1..(length - this.length()))
|
||||
for (i in 1..(length - this.length))
|
||||
sb.append(padChar)
|
||||
return sb.toString()
|
||||
return sb
|
||||
}
|
||||
|
||||
/**
|
||||
* Pads the string to the specified [length] at the end with the specified character or space.
|
||||
*
|
||||
* @param length the desired string length.
|
||||
* @param padChar the character to pad string with, if it has length less than the [length] specified. Space is used by default.
|
||||
* @returns Returns a string, of length at least [length], consisting of string prepended with [padChar] as many times.
|
||||
* as are necessary to reach that length.
|
||||
*/
|
||||
public fun String.padEnd(length: Int, padChar: Char = ' '): String
|
||||
= (this as CharSequence).padEnd(length, padChar).toString()
|
||||
|
||||
/**
|
||||
* Returns `true` if this nullable char sequence is either `null` or empty.
|
||||
*/
|
||||
@@ -204,24 +276,6 @@ public fun CharSequence.hasSurrogatePairAt(index: Int): Boolean {
|
||||
&& this[index + 1].isLowSurrogate()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a subsequence obtained by taking the characters at the given [indices] in this sequence.
|
||||
*/
|
||||
public fun CharSequence.slice(indices: Iterable<Int>): CharSequence {
|
||||
val sb = StringBuilder()
|
||||
for (i in indices) {
|
||||
sb.append(get(i))
|
||||
}
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a subsequence of this sequence specified by given [range].
|
||||
*/
|
||||
public fun CharSequence.slice(range: IntRange): CharSequence {
|
||||
return subSequence(range.start, range.end + 1) // inclusive
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a substring specified by the given [range].
|
||||
*/
|
||||
@@ -345,97 +399,172 @@ public fun String.substringAfterLast(delimiter: String, missingDelimiterValue: S
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string with content of this char sequence where its part at the given range
|
||||
* Returns a char sequence with content of this char sequence where its part at the given range
|
||||
* is replaced with the [replacement] char sequence.
|
||||
* @param firstIndex the index of the first character to be replaced.
|
||||
* @param lastIndex the index of the first character after the replacement to keep in the string.
|
||||
*/
|
||||
public fun CharSequence.replaceRange(firstIndex: Int, lastIndex: Int, replacement: CharSequence): String {
|
||||
public fun CharSequence.replaceRange(firstIndex: Int, lastIndex: Int, replacement: CharSequence): CharSequence {
|
||||
if (lastIndex < firstIndex)
|
||||
throw IndexOutOfBoundsException("Last index ($lastIndex) is less than first index ($firstIndex)")
|
||||
val sb = StringBuilder()
|
||||
sb.append(this, 0, firstIndex)
|
||||
sb.append(replacement)
|
||||
sb.append(this, lastIndex, length())
|
||||
return sb.toString()
|
||||
return sb
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string with content of this char sequence where its part at the given [range]
|
||||
* Replaces the part of the string at the given range with the [replacement] char sequence.
|
||||
* @param firstIndex the index of the first character to be replaced.
|
||||
* @param lastIndex the index of the first character after the replacement to keep in the string.
|
||||
*/
|
||||
public fun String.replaceRange(firstIndex: Int, lastIndex: Int, replacement: CharSequence): String
|
||||
= (this as CharSequence).replaceRange(firstIndex, lastIndex, replacement).toString()
|
||||
|
||||
/**
|
||||
* Returns a char sequence with content of this char sequence where its part at the given [range]
|
||||
* is replaced with the [replacement] char sequence.
|
||||
*
|
||||
* The end index of the [range] is included in the part to be replaced.
|
||||
*/
|
||||
public fun CharSequence.replaceRange(range: IntRange, replacement: CharSequence): String = replaceRange(range.start, range.end + 1, replacement)
|
||||
public fun CharSequence.replaceRange(range: IntRange, replacement: CharSequence): CharSequence
|
||||
= replaceRange(range.start, range.end + 1, replacement)
|
||||
|
||||
/**
|
||||
* Returns a string with content of this char sequence where its part at the given range is removed.
|
||||
* Replace the part of string at the given [range] with the [replacement] string.
|
||||
*
|
||||
* The end index of the [range] is included in the part to be replaced.
|
||||
*/
|
||||
public fun String.replaceRange(range: IntRange, replacement: CharSequence): String
|
||||
= replaceRange(range.start, range.end + 1, replacement)
|
||||
|
||||
/**
|
||||
* Returns a char sequence with content of this char sequence where its part at the given range is removed.
|
||||
*
|
||||
* @param firstIndex the index of the first character to be removed.
|
||||
* @param lastIndex the index of the first character after the removed part to keep in the string.
|
||||
*
|
||||
* [lastIndex] is not included in the removed part.
|
||||
*/
|
||||
public fun CharSequence.removeRange(firstIndex: Int, lastIndex: Int): String {
|
||||
public fun CharSequence.removeRange(firstIndex: Int, lastIndex: Int): CharSequence {
|
||||
if (lastIndex < firstIndex)
|
||||
throw IndexOutOfBoundsException("Last index ($lastIndex) is less than first index ($firstIndex)")
|
||||
|
||||
if (lastIndex == firstIndex)
|
||||
return this.toString()
|
||||
return this.subSequence(0, length)
|
||||
|
||||
val sb = StringBuilder(length() - (lastIndex - firstIndex))
|
||||
sb.append(this, 0, firstIndex)
|
||||
sb.append(this, lastIndex, length())
|
||||
return sb.toString()
|
||||
return sb
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string with content of this char sequence where its part at the given [range] is removed.
|
||||
* Removes the part of a string at a given range.
|
||||
* @param firstIndex the index of the first character to be removed.
|
||||
* @param lastIndex the index of the first character after the removed part to keep in the string.
|
||||
*
|
||||
* [lastIndex] is not included in the removed part.
|
||||
*/
|
||||
public fun String.removeRange(firstIndex: Int, lastIndex: Int): String
|
||||
= (this as CharSequence).removeRange(firstIndex, lastIndex).toString()
|
||||
|
||||
/**
|
||||
* Returns a char sequence with content of this char sequence where its part at the given [range] is removed.
|
||||
*
|
||||
* The end index of the [range] is included in the removed part.
|
||||
*/
|
||||
public fun CharSequence.removeRange(range: Range<Int>): String = removeRange(range.start, range.end + 1)
|
||||
public fun CharSequence.removeRange(range: IntRange): CharSequence = removeRange(range.start, range.end + 1)
|
||||
|
||||
/**
|
||||
* Removes the part of a string at the given [range].
|
||||
*
|
||||
* The end index of the [range] is included in the removed part.
|
||||
*/
|
||||
public fun String.removeRange(range: IntRange): String = removeRange(range.start, range.end + 1)
|
||||
|
||||
/**
|
||||
* If this char sequence starts with the given [prefix], returns a new char sequence
|
||||
* with the prefix removed. Otherwise, returns a new char sequence with the same characters.
|
||||
*/
|
||||
public fun CharSequence.removePrefix(prefix: CharSequence): CharSequence {
|
||||
if (startsWith(prefix)) {
|
||||
return subSequence(prefix.length, length)
|
||||
}
|
||||
return subSequence(0, length)
|
||||
}
|
||||
|
||||
/**
|
||||
* If this string starts with the given [prefix], returns a copy of this string
|
||||
* with the prefix removed. Otherwise, returns this string.
|
||||
*/
|
||||
public fun String.removePrefix(prefix: String): String {
|
||||
public fun String.removePrefix(prefix: CharSequence): String {
|
||||
if (startsWith(prefix)) {
|
||||
return substring(prefix.length())
|
||||
return substring(prefix.length)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* If this char sequence ends with the given [suffix], returns a new char sequence
|
||||
* with the suffix removed. Otherwise, returns a new char sequence with the same characters.
|
||||
*/
|
||||
public fun CharSequence.removeSuffix(suffix: CharSequence): CharSequence {
|
||||
if (endsWith(suffix)) {
|
||||
return subSequence(0, length - suffix.length)
|
||||
}
|
||||
return subSequence(0, length)
|
||||
}
|
||||
|
||||
/**
|
||||
* If this string ends with the given [suffix], returns a copy of this string
|
||||
* with the suffix removed. Otherwise, returns this string.
|
||||
*/
|
||||
public fun String.removeSuffix(suffix: String): String {
|
||||
public fun String.removeSuffix(suffix: CharSequence): String {
|
||||
if (endsWith(suffix)) {
|
||||
return substring(0, length() - suffix.length())
|
||||
return substring(0, length - suffix.length)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* When this char sequence starts with the given [prefix] and ends with the given [suffix],
|
||||
* returns a new char sequence having both the given [prefix] and [suffix] removed.
|
||||
* Otherwise returns a new char sequence with the same characters.
|
||||
*/
|
||||
public fun CharSequence.removeSurrounding(prefix: CharSequence, suffix: CharSequence): CharSequence {
|
||||
if (startsWith(prefix) && endsWith(suffix)) {
|
||||
return subSequence(prefix.length, length - suffix.length)
|
||||
}
|
||||
return subSequence(0, length)
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from a string both the given [prefix] and [suffix] if and only if
|
||||
* it starts with the [prefix] and ends with the [suffix].
|
||||
* Otherwise returns this string unchanged.
|
||||
*/
|
||||
public fun String.removeSurrounding(prefix: String, suffix: String): String {
|
||||
public fun String.removeSurrounding(prefix: CharSequence, suffix: CharSequence): String {
|
||||
if (startsWith(prefix) && endsWith(suffix)) {
|
||||
return substring(prefix.length(), length() - suffix.length())
|
||||
return substring(prefix.length, length - suffix.length)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* When this char sequence starts with and ends with the given [delimiter],
|
||||
* returns a new char sequence having this [delimiter] removed both from the start and end.
|
||||
* Otherwise returns a new char sequence with the same characters.
|
||||
*/
|
||||
public fun CharSequence.removeSurrounding(delimiter: CharSequence): CharSequence = removeSurrounding(delimiter, delimiter)
|
||||
|
||||
/**
|
||||
* Removes the given [delimiter] string from both the start and the end of this string
|
||||
* if and only if it starts with and ends with the [delimiter].
|
||||
* Otherwise returns this string unchanged.
|
||||
*/
|
||||
public fun String.removeSurrounding(delimiter: String): String = removeSurrounding(delimiter, delimiter)
|
||||
public fun String.removeSurrounding(delimiter: CharSequence): String = removeSurrounding(delimiter, delimiter)
|
||||
|
||||
/**
|
||||
* Replace part of string before the first occurrence of given delimiter with the [replacement] string.
|
||||
|
||||
@@ -8,140 +8,6 @@ import java.util.NoSuchElementException
|
||||
import kotlin.text.MatchResult
|
||||
import kotlin.text.Regex
|
||||
|
||||
/**
|
||||
* Returns the string with leading and trailing characters matching the [predicate] trimmed.
|
||||
*/
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
inline public fun String.trim(predicate: (Char) -> Boolean): String {
|
||||
var startIndex = 0
|
||||
var endIndex = length() - 1
|
||||
var startFound = false
|
||||
|
||||
while (startIndex <= endIndex) {
|
||||
val index = if (!startFound) startIndex else endIndex
|
||||
val match = predicate(this[index])
|
||||
|
||||
if (!startFound) {
|
||||
if (!match)
|
||||
startFound = true
|
||||
else
|
||||
startIndex += 1
|
||||
}
|
||||
else {
|
||||
if (!match)
|
||||
break
|
||||
else
|
||||
endIndex -= 1
|
||||
}
|
||||
}
|
||||
|
||||
return substring(startIndex, endIndex + 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string with leading characters matching the [predicate] trimmed.
|
||||
*/
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
inline public fun String.trimStart(predicate: (Char) -> Boolean): String {
|
||||
for (index in this.indices)
|
||||
if (!predicate(this[index]))
|
||||
return substring(index)
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string with trailing characters matching the [predicate] trimmed.
|
||||
*/
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
inline public fun String.trimEnd(predicate: (Char) -> Boolean): String {
|
||||
for (index in this.indices.reversed())
|
||||
if (!predicate(this[index]))
|
||||
return substring(0, index + 1)
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string with leading and trailing characters in the [chars] array trimmed.
|
||||
*/
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.trim(vararg chars: Char): String = trim { it in chars }
|
||||
|
||||
/**
|
||||
* Returns the string with leading and trailing characters in the [chars] array trimmed.
|
||||
*/
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.trimStart(vararg chars: Char): String = trimStart { it in chars }
|
||||
|
||||
/**
|
||||
* Returns the string with trailing characters in the [chars] array trimmed.
|
||||
*/
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.trimEnd(vararg chars: Char): String = trimEnd { it in chars }
|
||||
|
||||
/**
|
||||
* Returns a string with leading and trailing whitespace trimmed.
|
||||
*/
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.trim(): String = trim { it.isWhitespace() }
|
||||
|
||||
/**
|
||||
* Returns a string with leading whitespace removed.
|
||||
*/
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.trimStart(): String = trimStart { it.isWhitespace() }
|
||||
|
||||
/**
|
||||
* Returns a string with trailing whitespace removed.
|
||||
*/
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.trimEnd(): String = trimEnd { it.isWhitespace() }
|
||||
|
||||
/**
|
||||
* Left pad a String with a specified character or space.
|
||||
*
|
||||
* @param length the desired string length.
|
||||
* @param padChar the character to pad string with, if it has length less than the [length] specified. Space is used by default.
|
||||
* @returns Returns a string, of length at least [length], consisting of string prepended with [padChar] as many times.
|
||||
* as are necessary to reach that length.
|
||||
*/
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.padStart(length: Int, padChar: Char = ' '): String {
|
||||
if (length < 0)
|
||||
throw IllegalArgumentException("String length $length is less than zero.")
|
||||
if (length <= this.length())
|
||||
return this
|
||||
|
||||
val sb = StringBuilder(length)
|
||||
for (i in 1..(length - this.length()))
|
||||
sb.append(padChar)
|
||||
sb.append(this)
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Right pad a String with a specified character or space.
|
||||
*
|
||||
* @param length the desired string length.
|
||||
* @param padChar the character to pad string with, if it has length less than the [length] specified. Space is used by default.
|
||||
* @returns Returns a string, of length at least [length], consisting of string prepended with [padChar] as many times.
|
||||
* as are necessary to reach that length.
|
||||
*/
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.padEnd(length: Int, padChar: Char = ' '): String {
|
||||
if (length < 0)
|
||||
throw IllegalArgumentException("String length $length is less than zero.")
|
||||
if (length <= this.length())
|
||||
return this
|
||||
|
||||
val sb = StringBuilder(length)
|
||||
sb.append(this)
|
||||
for (i in 1..(length - this.length()))
|
||||
sb.append(padChar)
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
/** Returns `true` if the string is not `null` and not empty */
|
||||
@Deprecated("Use !isNullOrEmpty() or isNullOrEmpty().not() for nullable strings.", ReplaceWith("this != null && this.isNotEmpty()"), DeprecationLevel.ERROR)
|
||||
@kotlin.jvm.JvmName("isNotEmptyNullable")
|
||||
@@ -273,69 +139,7 @@ public fun String.substringAfterLast(delimiter: String, missingDelimiterValue: S
|
||||
val index = lastIndexOf(delimiter)
|
||||
return if (index == -1) missingDelimiterValue else substring(index + delimiter.length(), length())
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Replaces the part of the string at the given range with the [replacement] string.
|
||||
* @param firstIndex the index of the first character to be replaced.
|
||||
* @param lastIndex the index of the first character after the replacement to keep in the string.
|
||||
*/
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.replaceRange(firstIndex: Int, lastIndex: Int, replacement: String): String {
|
||||
if (lastIndex < firstIndex)
|
||||
throw IndexOutOfBoundsException("Last index ($lastIndex) is less than first index ($firstIndex)")
|
||||
val sb = StringBuilder()
|
||||
sb.append(this, 0, firstIndex)
|
||||
sb.append(replacement)
|
||||
sb.append(this, lastIndex, length())
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the part of string at the given [range] with the [replacement] string.
|
||||
*
|
||||
* The end index of the [range] is included in the part to be replaced.
|
||||
*/
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.replaceRange(range: IntRange, replacement: String): String = replaceRange(range.start, range.end + 1, replacement)
|
||||
|
||||
/**
|
||||
* Removes the part of a string at a given range.
|
||||
* @param firstIndex the index of the first character to be removed.
|
||||
* @param lastIndex the index of the first character after the removed part to keep in the string.
|
||||
*
|
||||
* [lastIndex] is not included in the removed part.
|
||||
*/
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.removeRange(firstIndex: Int, lastIndex: Int): String {
|
||||
if (lastIndex < firstIndex)
|
||||
throw IndexOutOfBoundsException("Last index ($lastIndex) is less than first index ($firstIndex)")
|
||||
|
||||
if (lastIndex == firstIndex)
|
||||
return this
|
||||
|
||||
val sb = StringBuilder(length() - (lastIndex - firstIndex))
|
||||
sb.append(this, 0, firstIndex)
|
||||
sb.append(this, lastIndex, length())
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the part of a string at the given [range].
|
||||
*
|
||||
* The end index of the [range] is included in the removed part.
|
||||
*/
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.removeRange(range: IntRange): String = removeRange(range.start, range.end + 1)
|
||||
|
||||
/*
|
||||
|
||||
/**
|
||||
* Removes the given [delimiter] string from both the start and the end of this string
|
||||
* if and only if it starts with and ends with the [delimiter].
|
||||
* Otherwise returns this string unchanged.
|
||||
*/
|
||||
public fun String.removeSurrounding(delimiter: String): String = removeSurrounding(delimiter, delimiter)
|
||||
|
||||
/**
|
||||
* Replace part of string before the first occurrence of given delimiter with the [replacement] string.
|
||||
@@ -410,6 +214,30 @@ public fun String.replaceBeforeLast(delimiter: String, replacement: String, miss
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.replaceRange(firstIndex: Int, lastIndex: Int, replacement: String): String
|
||||
= replaceRange(firstIndex, lastIndex, replacement)
|
||||
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.replaceRange(range: IntRange, replacement: String): String
|
||||
= replaceRange(range.start, range.end + 1, replacement)
|
||||
|
||||
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.removePrefix(prefix: String): String = removePrefix(prefix)
|
||||
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.removeSuffix(suffix: String): String = removeSuffix(suffix)
|
||||
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.removeSurrounding(prefix: String, suffix: String): String = removeSurrounding(prefix, suffix)
|
||||
|
||||
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
public fun String.removeSurrounding(delimiter: String): String = removeSurrounding(delimiter, delimiter)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns a new string obtained by replacing each substring of this string that matches the given regular expression
|
||||
* with the given [replacement].
|
||||
|
||||
@@ -25,8 +25,8 @@ fun withTwoCharSequenceArgs(f: ((String) -> CharSequence, (String) -> CharSequen
|
||||
f(arg1Builder, arg2Builder)
|
||||
}
|
||||
|
||||
fun assertContentEquals(expected: String, actual: CharSequence) {
|
||||
assertEquals(expected, actual.toString())
|
||||
fun assertContentEquals(expected: String, actual: CharSequence, message: String? = null) {
|
||||
assertEquals(expected, actual.toString(), message)
|
||||
}
|
||||
|
||||
// helper predicates available on both platforms
|
||||
@@ -236,8 +236,8 @@ class StringTest {
|
||||
val s = arg1("sample text")
|
||||
val replacement = arg2("??")
|
||||
|
||||
assertEquals("sa??e text", s.replaceRange(2, 5, replacement))
|
||||
assertEquals("sa?? text", s.replaceRange(2..5, replacement))
|
||||
assertContentEquals("sa??e text", s.replaceRange(2, 5, replacement))
|
||||
assertContentEquals("sa?? text", s.replaceRange(2..5, replacement))
|
||||
assertFails {
|
||||
s.replaceRange(5..2, replacement)
|
||||
}
|
||||
@@ -246,21 +246,21 @@ class StringTest {
|
||||
}
|
||||
|
||||
// symmetry with indices
|
||||
assertEquals(replacement.toString(), s.replaceRange(s.indices, replacement))
|
||||
assertContentEquals(replacement.toString(), s.replaceRange(s.indices, replacement))
|
||||
}
|
||||
|
||||
@test fun removeRange() = withOneCharSequenceArg("sample text") { s ->
|
||||
assertEquals("sae text", s.removeRange(2, 5))
|
||||
assertEquals("sa text", s.removeRange(2..5))
|
||||
assertContentEquals("sae text", s.removeRange(2, 5))
|
||||
assertContentEquals("sa text", s.removeRange(2..5))
|
||||
|
||||
assertEquals(s.toString(), s.removeRange(2,2))
|
||||
assertContentEquals(s.toString(), s.removeRange(2,2))
|
||||
|
||||
// symmetry with indices
|
||||
assertEquals("", s.removeRange(s.indices))
|
||||
assertContentEquals("", s.removeRange(s.indices))
|
||||
|
||||
// symmetry with replaceRange
|
||||
assertEquals(s.replaceRange(2, 5, ""), s.removeRange(2, 5))
|
||||
assertEquals(s.replaceRange(2..5, ""), s.removeRange(2..5))
|
||||
assertContentEquals(s.toString().replaceRange(2, 5, ""), s.removeRange(2, 5))
|
||||
assertContentEquals(s.toString().replaceRange(2..5, ""), s.removeRange(2..5))
|
||||
}
|
||||
|
||||
@test fun substringDelimited() {
|
||||
@@ -318,43 +318,43 @@ class StringTest {
|
||||
}
|
||||
|
||||
@test fun trimStart() = withOneCharSequenceArg { arg1 ->
|
||||
fun String.trimStart(): String = arg1(this).trimStart()
|
||||
assertEquals("", "".trimStart())
|
||||
assertEquals("a", "a".trimStart())
|
||||
assertEquals("a", " a".trimStart())
|
||||
assertEquals("a", " a".trimStart())
|
||||
assertEquals("a ", " a ".trimStart())
|
||||
assertEquals("a b", " a b".trimStart())
|
||||
assertEquals("a b ", " a b ".trimStart())
|
||||
assertEquals("a", " \u00A0 a".trimStart())
|
||||
fun String.trimStartCS(): CharSequence = arg1(this).trimStart()
|
||||
assertContentEquals("", "".trimStartCS())
|
||||
assertContentEquals("a", "a".trimStartCS())
|
||||
assertContentEquals("a", " a".trimStartCS())
|
||||
assertContentEquals("a", " a".trimStartCS())
|
||||
assertContentEquals("a ", " a ".trimStartCS())
|
||||
assertContentEquals("a b", " a b".trimStartCS())
|
||||
assertContentEquals("a b ", " a b ".trimStartCS())
|
||||
assertContentEquals("a", " \u00A0 a".trimStartCS())
|
||||
|
||||
assertEquals("a", "\ta".trimStart())
|
||||
assertEquals("a", "\t\ta".trimStart())
|
||||
assertEquals("a", "\ra".trimStart())
|
||||
assertEquals("a", "\na".trimStart())
|
||||
assertContentEquals("a", "\ta".trimStartCS())
|
||||
assertContentEquals("a", "\t\ta".trimStartCS())
|
||||
assertContentEquals("a", "\ra".trimStartCS())
|
||||
assertContentEquals("a", "\na".trimStartCS())
|
||||
|
||||
assertEquals("a=", arg1("-=-=a=").trimStart('-','='))
|
||||
assertEquals("123a", arg1("ab123a").trimStart { it < '0' || it > '9' }) // TODO: Use !it.isDigit when available in JS
|
||||
assertContentEquals("a=", arg1("-=-=a=").trimStart('-','='))
|
||||
assertContentEquals("123a", arg1("ab123a").trimStart { !it.isAsciiDigit() })
|
||||
}
|
||||
|
||||
@test fun trimEnd() = withOneCharSequenceArg { arg1 ->
|
||||
fun String.trimEnd(): String = arg1(this).trimEnd()
|
||||
assertEquals("", "".trimEnd())
|
||||
assertEquals("a", "a".trimEnd())
|
||||
assertEquals("a", "a ".trimEnd())
|
||||
assertEquals("a", "a ".trimEnd())
|
||||
assertEquals(" a", " a ".trimEnd())
|
||||
assertEquals("a b", "a b ".trimEnd())
|
||||
assertEquals(" a b", " a b ".trimEnd())
|
||||
assertEquals("a", "a \u00A0 ".trimEnd())
|
||||
fun String.trimEndCS(): CharSequence = arg1(this).trimEnd()
|
||||
assertContentEquals("", "".trimEndCS())
|
||||
assertContentEquals("a", "a".trimEndCS())
|
||||
assertContentEquals("a", "a ".trimEndCS())
|
||||
assertContentEquals("a", "a ".trimEndCS())
|
||||
assertContentEquals(" a", " a ".trimEndCS())
|
||||
assertContentEquals("a b", "a b ".trimEndCS())
|
||||
assertContentEquals(" a b", " a b ".trimEndCS())
|
||||
assertContentEquals("a", "a \u00A0 ".trimEndCS())
|
||||
|
||||
assertEquals("a", "a\t".trimEnd())
|
||||
assertEquals("a", "a\t\t".trimEnd())
|
||||
assertEquals("a", "a\r".trimEnd())
|
||||
assertEquals("a", "a\n".trimEnd())
|
||||
assertContentEquals("a", "a\t".trimEndCS())
|
||||
assertContentEquals("a", "a\t\t".trimEndCS())
|
||||
assertContentEquals("a", "a\r".trimEndCS())
|
||||
assertContentEquals("a", "a\n".trimEndCS())
|
||||
|
||||
assertEquals("=a", arg1("=a=-=-").trimEnd('-','='))
|
||||
assertEquals("ab123", arg1("ab123a").trimEnd { it < '0' || it > '9' }) // TODO: Use !it.isDigit when available in JS
|
||||
assertContentEquals("=a", arg1("=a=-=-").trimEnd('-','='))
|
||||
assertContentEquals("ab123", arg1("ab123a").trimEnd { !it.isAsciiDigit() })
|
||||
}
|
||||
|
||||
@test fun trimStartAndEnd() = withOneCharSequenceArg { arg1 ->
|
||||
@@ -369,9 +369,9 @@ class StringTest {
|
||||
" \u00A0 a \u00A0 "
|
||||
)
|
||||
|
||||
for (example in examples.map { arg1(it) }) {
|
||||
assertEquals(example.trim(), example.trimEnd().trimStart())
|
||||
assertEquals(example.trim(), example.trimStart().trimEnd())
|
||||
for ((source, example) in examples.map { it to arg1(it) }) {
|
||||
assertContentEquals(source.trimEnd().trimStart(), example.trim())
|
||||
assertContentEquals(source.trimStart().trimEnd(), example.trim())
|
||||
}
|
||||
|
||||
val examplesForPredicate = arrayOf("123",
|
||||
@@ -379,57 +379,88 @@ class StringTest {
|
||||
)
|
||||
|
||||
val trimChars = charArrayOf('-', '=')
|
||||
val trimPredicate = { it: Char -> it < '0' || it > '9' } // TODO: Use !it.isDigit when available in JS
|
||||
for (example in examplesForPredicate.map { arg1(it) }) {
|
||||
assertEquals(example.trimStart(*trimChars).trimEnd(*trimChars), example.trim(*trimChars))
|
||||
assertEquals(example.trimStart(trimPredicate).trimEnd(trimPredicate), example.trim(trimPredicate))
|
||||
val trimPredicate = { it: Char -> !it.isAsciiDigit() }
|
||||
for ((source, example) in examplesForPredicate.map { it to arg1(it) }) {
|
||||
assertContentEquals(source.trimStart(*trimChars).trimEnd(*trimChars), example.trim(*trimChars))
|
||||
assertContentEquals(source.trimStart(trimPredicate).trimEnd(trimPredicate), example.trim(trimPredicate))
|
||||
}
|
||||
}
|
||||
|
||||
@test fun padStart() = withOneCharSequenceArg { arg1 ->
|
||||
fun String.padStart(length: Int): String = arg1(this).padStart(length)
|
||||
assertEquals("s", "s".padStart(0))
|
||||
assertEquals("s", "s".padStart(1))
|
||||
assertEquals(" ", "".padStart(2))
|
||||
assertEquals("--s", arg1("s").padStart(3, '-'))
|
||||
val s = arg1("s")
|
||||
assertContentEquals("s", s.padStart(0))
|
||||
assertContentEquals("s", s.padStart(1))
|
||||
assertContentEquals("--s", s.padStart(3, '-'))
|
||||
assertContentEquals(" ", arg1("").padStart(2))
|
||||
assertFails {
|
||||
"s".padStart(-1)
|
||||
s.padStart(-1)
|
||||
}
|
||||
}
|
||||
|
||||
@test fun padEnd() = withOneCharSequenceArg { arg1 ->
|
||||
fun String.padEnd(length: Int): String = arg1(this).padEnd(length)
|
||||
assertEquals("s", "s".padEnd(0))
|
||||
assertEquals("s", "s".padEnd(1))
|
||||
assertEquals(" ", "".padEnd(2))
|
||||
assertEquals("s--", arg1("s").padEnd(3, '-'))
|
||||
val s = arg1("s")
|
||||
assertContentEquals("s", s.padEnd(0))
|
||||
assertContentEquals("s", s.padEnd(1))
|
||||
assertContentEquals("s--", s.padEnd(3, '-'))
|
||||
assertContentEquals(" ", arg1("").padEnd(2))
|
||||
assertFails {
|
||||
"s".padEnd(-1)
|
||||
s.padEnd(-1)
|
||||
}
|
||||
}
|
||||
|
||||
@test fun removePrefix() {
|
||||
assertEquals("fix", "prefix".removePrefix("pre"), "Removes prefix")
|
||||
assertEquals("prefix", "preprefix".removePrefix("pre"), "Removes prefix once")
|
||||
assertEquals("sample", "sample".removePrefix("value"))
|
||||
@test fun removePrefix() = withOneCharSequenceArg("pre") { prefix ->
|
||||
assertEquals("fix", "prefix".removePrefix(prefix), "Removes prefix")
|
||||
assertEquals("prefix", "preprefix".removePrefix(prefix), "Removes prefix once")
|
||||
assertEquals("sample", "sample".removePrefix(prefix))
|
||||
assertEquals("sample", "sample".removePrefix(""))
|
||||
}
|
||||
|
||||
@test fun removeSuffix() {
|
||||
assertEquals("suf", "suffix".removeSuffix("fix"), "Removes suffix")
|
||||
assertEquals("suffix", "suffixfix".removeSuffix("fix"), "Removes suffix once")
|
||||
assertEquals("sample", "sample".removeSuffix("value"))
|
||||
@test fun removeSuffix() = withOneCharSequenceArg("fix") { suffix ->
|
||||
assertEquals("suf", "suffix".removeSuffix(suffix), "Removes suffix")
|
||||
assertEquals("suffix", "suffixfix".removeSuffix(suffix), "Removes suffix once")
|
||||
assertEquals("sample", "sample".removeSuffix(suffix))
|
||||
assertEquals("sample", "sample".removeSuffix(""))
|
||||
}
|
||||
|
||||
@test fun removeSurrounding() {
|
||||
assertEquals("value", "<value>".removeSurrounding("<", ">"))
|
||||
assertEquals("<value>", "<<value>>".removeSurrounding("<", ">"), "Removes surrounding once")
|
||||
assertEquals("<value", "<value".removeSurrounding("<", ">"), "Only removes surrounding when both prefix and suffix present")
|
||||
assertEquals("value>", "value>".removeSurrounding("<", ">"), "Only removes surrounding when both prefix and suffix present")
|
||||
assertEquals("value", "value".removeSurrounding("<", ">"))
|
||||
@test fun removeSurrounding() = withOneCharSequenceArg { arg1 ->
|
||||
val pre = arg1("<")
|
||||
val post = arg1(">")
|
||||
assertEquals("value", "<value>".removeSurrounding(pre, post))
|
||||
assertEquals("<value>", "<<value>>".removeSurrounding(pre, post), "Removes surrounding once")
|
||||
assertEquals("<value", "<value".removeSurrounding(pre, post), "Only removes surrounding when both prefix and suffix present")
|
||||
assertEquals("value>", "value>".removeSurrounding(pre, post), "Only removes surrounding when both prefix and suffix present")
|
||||
assertEquals("value", "value".removeSurrounding(pre, post))
|
||||
}
|
||||
|
||||
@test fun removePrefixCharSequence() = withTwoCharSequenceArgs { arg1, arg2 ->
|
||||
fun String.removePrefix(prefix: String) = arg1(this).removePrefix(arg2(prefix))
|
||||
val prefix = "pre"
|
||||
|
||||
assertContentEquals("fix", "prefix".removePrefix(prefix), "Removes prefix")
|
||||
assertContentEquals("prefix", "preprefix".removePrefix(prefix), "Removes prefix once")
|
||||
assertContentEquals("sample", "sample".removePrefix(prefix))
|
||||
assertContentEquals("sample", "sample".removePrefix(""))
|
||||
}
|
||||
|
||||
@test fun removeSuffixCharSequence() = withTwoCharSequenceArgs { arg1, arg2 ->
|
||||
fun String.removeSuffix(suffix: String) = arg1(this).removeSuffix(arg2(suffix))
|
||||
val suffix = "fix"
|
||||
|
||||
assertContentEquals("suf", "suffix".removeSuffix(suffix), "Removes suffix")
|
||||
assertContentEquals("suffix", "suffixfix".removeSuffix(suffix), "Removes suffix once")
|
||||
assertContentEquals("sample", "sample".removeSuffix(suffix))
|
||||
assertContentEquals("sample", "sample".removeSuffix(""))
|
||||
}
|
||||
|
||||
@test fun removeSurroundingCharSequence() = withTwoCharSequenceArgs { arg1, arg2 ->
|
||||
fun String.removeSurrounding(prefix: String, postfix: String) = arg1(this).removeSurrounding(arg2(prefix), arg2(postfix))
|
||||
|
||||
assertContentEquals("value", "<value>".removeSurrounding("<", ">"))
|
||||
assertContentEquals("<value>", "<<value>>".removeSurrounding("<", ">"), "Removes surrounding once")
|
||||
assertContentEquals("<value", "<value".removeSurrounding("<", ">"), "Only removes surrounding when both prefix and suffix present")
|
||||
assertContentEquals("value>", "value>".removeSurrounding("<", ">"), "Only removes surrounding when both prefix and suffix present")
|
||||
assertContentEquals("value", "value".removeSurrounding("<", ">"))
|
||||
}
|
||||
|
||||
/*
|
||||
// unit test commented out until rangesDelimitiedBy would become public
|
||||
|
||||
Reference in New Issue
Block a user