# Class Strings

java.lang.Object
org.apache.commons.lang3.Strings

public abstract class Strings extends Object
String operations where you choose case-sensitive `CS` vs. case-insensitive `CI` through a singleton instance.

Since:
  3.18.0
See Also:
  - `CharSequenceUtils`
  - `StringUtils`

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static class`
  `Strings.Builder`
  Builds `Strings` instances.

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static final Strings`
  `CI`
  The Case-Insensitive singleton instance.
  `static final Strings`
  `CS`
  The Case-Sensitive singleton instance.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `String`
  `appendIfMissing(String str, CharSequence suffix, CharSequence... suffixes)`
  Appends the suffix to the end of the string if the string does not already end with the suffix.
  `static final Strings.Builder`
  `builder()`
  Constructs a new `Strings.Builder` instance.
  `abstract int`
  `compare(String str1, String str2)`
  Compare two Strings lexicographically, like `String.compareTo(String)`.
  `abstract boolean`
  `contains(CharSequence seq, CharSequence searchSeq)`
  Tests if CharSequence contains a search CharSequence, handling `null`.
  `boolean`
  `containsAny(CharSequence cs, CharSequence... searchCharSequences)`
  Tests if the CharSequence contains any of the CharSequences in the given array.
  `boolean`
  `endsWith(CharSequence str, CharSequence suffix)`
  Tests if a CharSequence ends with a specified suffix.
  `boolean`
  `endsWithAny(CharSequence sequence, CharSequence... searchStrings)`
  Tests if a CharSequence ends with any of the provided suffixes.
  `abstract boolean`
  `equals(CharSequence cs1, CharSequence cs2)`
  Compares two CharSequences, returning `true` if they represent equal sequences of characters.
  `abstract boolean`
  `equals(String str1, String str2)`
  Compares two CharSequences, returning `true` if they represent equal sequences of characters.
  `boolean`
  `equalsAny(CharSequence string, CharSequence... searchStrings)`
  Compares given `string` to a CharSequences vararg of `searchStrings`, returning `true` if the `string` is equal to any of the `searchStrings`.
  `int`
  `indexOf(CharSequence seq, CharSequence searchSeq)`
  Finds the first index within a CharSequence, handling `null`.
  `abstract int`
  `indexOf(CharSequence seq, CharSequence searchSeq, int startPos)`
  Finds the first index within a CharSequence, handling `null`.
  `boolean`
  `isCaseSensitive()`
  Tests whether to ignore case.
  `int`
  `lastIndexOf(CharSequence str, CharSequence searchStr)`
  Finds the last index within a CharSequence, handling `null`.
  `abstract int`
  `lastIndexOf(CharSequence seq, CharSequence searchSeq, int startPos)`
  Finds the last index within a CharSequence, handling `null`.
  `String`
  `prependIfMissing(String str, CharSequence prefix, CharSequence... prefixes)`
  Prepends the prefix to the start of the string if the string does not already start with any of the prefixes.
  `String`
  `remove(String str, String remove)`
  Removes all occurrences of a substring from within the source string.
  `String`
  `removeEnd(String str, CharSequence remove)`
  Case-insensitive removal of a substring if it is at the end of a source string, otherwise returns the source string.
  `String`
  `removeStart(String str, CharSequence remove)`
  Case-insensitive removal of a substring if it is at the beginning of a source string, otherwise returns the source string.
  `String`
  `replace(String text, String searchString, String replacement)`
  Case insensitively replaces all occurrences of a String within another String.
  `String`
  `replace(String text, String searchString, String replacement, int max)`
  Replaces a String with another String inside a larger String, for the first `max` values of the search String.
  `String`
  `replaceOnce(String text, String searchString, String replacement)`
  Replaces a String with another String inside a larger String, once.
  `boolean`
  `startsWith(CharSequence str, CharSequence prefix)`
  Tests if a CharSequence starts with a specified prefix.
  `boolean`
  `startsWithAny(CharSequence sequence, CharSequence... searchStrings)`
  Tests if a CharSequence starts with any of the provided prefixes.

  ### Methods inherited from class Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Field Details

  - ### CI

    public static final Strings CI
    The Case-Insensitive singleton instance.

  - ### CS

    public static final Strings CS
    The Case-Sensitive singleton instance.

- ## Method Details

  - ### builder

    public static final Strings.Builder builder()
    Constructs a new `Strings.Builder` instance.
    Returns:
      a new `Strings.Builder` instance.

  - ### appendIfMissing

    public String appendIfMissing(String str, CharSequence suffix, CharSequence... suffixes)
    Appends the suffix to the end of the string if the string does not already end with the suffix.

    Case-sensitive examples

        Strings.CS.appendIfMissing(null, null)      = null
        Strings.CS.appendIfMissing("abc", null)     = "abc"
        Strings.CS.appendIfMissing("", "xyz"        = "xyz"
        Strings.CS.appendIfMissing("abc", "xyz")    = "abcxyz"
        Strings.CS.appendIfMissing("abcxyz", "xyz") = "abcxyz"
        Strings.CS.appendIfMissing("abcXYZ", "xyz") = "abcXYZxyz"

    With additional suffixes:

        Strings.CS.appendIfMissing(null, null, null)       = null
        Strings.CS.appendIfMissing("abc", null, null)      = "abc"
        Strings.CS.appendIfMissing("", "xyz", null)        = "xyz"
        Strings.CS.appendIfMissing("abc", "xyz", new CharSequence[]{null}) = "abcxyz"
        Strings.CS.appendIfMissing("abc", "xyz", "")       = "abc"
        Strings.CS.appendIfMissing("abc", "xyz", "mno")    = "abcxyz"
        Strings.CS.appendIfMissing("abcxyz", "xyz", "mno") = "abcxyz"
        Strings.CS.appendIfMissing("abcmno", "xyz", "mno") = "abcmno"
        Strings.CS.appendIfMissing("abcXYZ", "xyz", "mno") = "abcXYZxyz"
        Strings.CS.appendIfMissing("abcMNO", "xyz", "mno") = "abcMNOxyz"

    Case-insensitive examples

        Strings.CI.appendIfMissing(null, null)      = null
        Strings.CI.appendIfMissing("abc", null)     = "abc"
        Strings.CI.appendIfMissing("", "xyz")       = "xyz"
        Strings.CI.appendIfMissing("abc", "xyz")    = "abcxyz"
        Strings.CI.appendIfMissing("abcxyz", "xyz") = "abcxyz"
        Strings.CI.appendIfMissing("abcXYZ", "xyz") = "abcXYZ"

    With additional suffixes:

        Strings.CI.appendIfMissing(null, null, null)       = null
        Strings.CI.appendIfMissing("abc", null, null)      = "abc"
        Strings.CI.appendIfMissing("", "xyz", null)        = "xyz"
        Strings.CI.appendIfMissing("abc", "xyz", new CharSequence[]{null}) = "abcxyz"
        Strings.CI.appendIfMissing("abc", "xyz", "")       = "abc"
        Strings.CI.appendIfMissing("abc", "xyz", "mno")    = "abcxyz"
        Strings.CI.appendIfMissing("abcxyz", "xyz", "mno") = "abcxyz"
        Strings.CI.appendIfMissing("abcmno", "xyz", "mno") = "abcmno"
        Strings.CI.appendIfMissing("abcXYZ", "xyz", "mno") = "abcXYZ"
        Strings.CI.appendIfMissing("abcMNO", "xyz", "mno") = "abcMNO"

    Parameters:
      `str` - The string.
      `suffix` - The suffix to append to the end of the string.
      `suffixes` - Additional suffixes that are valid terminators (optional).
    Returns:
      A new String if suffix was appended, the same string otherwise.

  - ### compare

    public abstract int compare(String str1, String str2)
    Compare two Strings lexicographically, like `String.compareTo(String)`.

    The return values are:

    - `int = 0`, if `str1` is equal to `str2` (or both `null`)
    - `int < 0`, if `str1` is less than `str2`
    - `int > 0`, if `str1` is greater than `str2`

    This is a `null` safe version of :

        str1.compareTo(str2)

    `null` value is considered less than non-`null` value. Two `null` references are considered equal.

    Case-sensitive examples

        Strings.CS.compare(null, null)   = 0
        Strings.CS.compare(null , "a")   < 0
        Strings.CS.compare("a", null)   > 0
        Strings.CS.compare("abc", "abc") = 0
        Strings.CS.compare("a", "b")     < 0
        Strings.CS.compare("b", "a")     > 0
        Strings.CS.compare("a", "B")     > 0
        Strings.CS.compare("ab", "abc")  < 0

    Case-insensitive examples

        Strings.CI.compare(null, null)   = 0
        Strings.CI.compare(null , "a")   < 0
        Strings.CI.compare("a", null)    > 0
        Strings.CI.compare("abc", "abc") = 0
        Strings.CI.compare("abc", "ABC") = 0
        Strings.CI.compare("a", "b")     < 0
        Strings.CI.compare("b", "a")     > 0
        Strings.CI.compare("a", "B")     < 0
        Strings.CI.compare("A", "b")     < 0
        Strings.CI.compare("ab", "ABC")  < 0

    Parameters:
      `str1` - the String to compare from
      `str2` - the String to compare to
    Returns:
      < 0, 0, > 0, if `str1` is respectively less, equal or greater than `str2`
    See Also:
      - `String.compareTo(String)`

  - ### contains

    public abstract boolean contains(CharSequence seq, CharSequence searchSeq)
    Tests if CharSequence contains a search CharSequence, handling `null`. This method uses `String.indexOf(String)` if possible.

    A `null` CharSequence will return `false`.

    Case-sensitive examples

        Strings.CS.contains(null, *)     = false
        Strings.CS.contains(*, null)     = false
        Strings.CS.contains("", "")      = true
        Strings.CS.contains("abc", "")   = true
        Strings.CS.contains("abc", "a")  = true
        Strings.CS.contains("abc", "z")  = false

    Case-insensitive examples

        Strings.CI.contains(null, *)    = false
        Strings.CI.contains(*, null)    = false
        Strings.CI.contains("", "")     = true
        Strings.CI.contains("abc", "")  = true
        Strings.CI.contains("abc", "a") = true
        Strings.CI.contains("abc", "z") = false
        Strings.CI.contains("abc", "A") = true
        Strings.CI.contains("abc", "Z") = false

    Parameters:
      `seq` - the CharSequence to check, may be null
      `searchSeq` - the CharSequence to find, may be null
    Returns:
      true if the CharSequence contains the search CharSequence, false if not or `null` string input

  - ### containsAny

    public boolean containsAny(CharSequence cs, CharSequence... searchCharSequences)
    Tests if the CharSequence contains any of the CharSequences in the given array.

    A `null` `cs` CharSequence will return `false`. A `null` or zero length search array will return `false`.

    Case-sensitive examples

        Strings.CS.containsAny(null, *)            = false
        Strings.CS.containsAny("", *)              = false
        Strings.CS.containsAny(*, null)            = false
        Strings.CS.containsAny(*, [])              = false
        Strings.CS.containsAny("abcd", "ab", null) = true
        Strings.CS.containsAny("abcd", "ab", "cd") = true
        Strings.CS.containsAny("abc", "d", "abc")  = true

    Case-insensitive examples

        Strings.CI.containsAny(null, *)            = false
        Strings.CI.containsAny("", *)              = false
        Strings.CI.containsAny(*, null)            = false
        Strings.CI.containsAny(*, [])              = false
        Strings.CI.containsAny("abcd", "ab", null) = true
        Strings.CI.containsAny("abcd", "ab", "cd") = true
        Strings.CI.containsAny("abc", "d", "abc")  = true
        Strings.CI.containsAny("abc", "D", "ABC")  = true
        Strings.CI.containsAny("ABC", "d", "abc")  = true

    Parameters:
      `cs` - The CharSequence to check, may be null
      `searchCharSequences` - The array of CharSequences to search for, may be null. Individual CharSequences may be null as well.
    Returns:
      `true` if any of the search CharSequences are found, `false` otherwise

  - ### endsWith

    public boolean endsWith(CharSequence str, CharSequence suffix)
    Tests if a CharSequence ends with a specified suffix.

    Case-sensitive examples

        Strings.CS.endsWith(null, null)      = true
        Strings.CS.endsWith(null, "def")     = false
        Strings.CS.endsWith("abcdef", null)  = false
        Strings.CS.endsWith("abcdef", "def") = true
        Strings.CS.endsWith("ABCDEF", "def") = false
        Strings.CS.endsWith("ABCDEF", "cde") = false
        Strings.CS.endsWith("ABCDEF", "")    = true

    Case-insensitive examples

        Strings.CI.endsWith(null, null)      = true
        Strings.CI.endsWith(null, "def")     = false
        Strings.CI.endsWith("abcdef", null)  = false
        Strings.CI.endsWith("abcdef", "def") = true
        Strings.CI.endsWith("ABCDEF", "def") = true
        Strings.CI.endsWith("ABCDEF", "cde") = false

    Parameters:
      `str` - the CharSequence to check, may be null.
      `suffix` - the suffix to find, may be null.
    Returns:
      `true` if the CharSequence starts with the prefix or both `null`.
    See Also:
      - `String.endsWith(String)`

  - ### endsWithAny

    public boolean endsWithAny(CharSequence sequence, CharSequence... searchStrings)
    Tests if a CharSequence ends with any of the provided suffixes.

    Case-sensitive examples

        Strings.CS.endsWithAny(null, null)                  = false
        Strings.CS.endsWithAny(null, new String[] {"abc"})  = false
        Strings.CS.endsWithAny("abcxyz", null)              = false
        Strings.CS.endsWithAny("abcxyz", new String[] {""}) = true
        Strings.CS.endsWithAny("abcxyz", new String[] {"xyz"}) = true
        Strings.CS.endsWithAny("abcxyz", new String[] {null, "xyz", "abc"}) = true
        Strings.CS.endsWithAny("abcXYZ", "def", "XYZ")      = true
        Strings.CS.endsWithAny("abcXYZ", "def", "xyz")      = false

    Parameters:
      `sequence` - the CharSequence to check, may be null
      `searchStrings` - the CharSequence suffixes to find, may be empty or contain `null`
    Returns:
      `true` if the input `sequence` is `null` AND no `searchStrings` are provided, or the input `sequence` ends in any of the provided `searchStrings`.
    See Also:
      - `endsWith(CharSequence, CharSequence)`

  - ### equals

    public abstract boolean equals(CharSequence cs1, CharSequence cs2)
    Compares two CharSequences, returning `true` if they represent equal sequences of characters.

    `null`s are handled without exceptions. Two `null` references are considered to be equal.

    Case-sensitive examples

        Strings.CS.equals(null, null)   = true
        Strings.CS.equals(null, "abc")  = false
        Strings.CS.equals("abc", null)  = false
        Strings.CS.equals("abc", "abc") = true
        Strings.CS.equals("abc", "ABC") = false

    Case-insensitive examples

        Strings.CI.equals(null, null)   = true
        Strings.CI.equals(null, "abc")  = false
        Strings.CI.equals("abc", null)  = false
        Strings.CI.equals("abc", "abc") = true
        Strings.CI.equals("abc", "ABC") = true

    Parameters:
      `cs1` - the first CharSequence, may be `null`
      `cs2` - the second CharSequence, may be `null`
    Returns:
      `true` if the CharSequences are equal (case-sensitive), or both `null`
    See Also:
      - `Object.equals(Object)`
      - `String.compareTo(String)`
      - `String.equalsIgnoreCase(String)`

  - ### equals

    public abstract boolean equals(String str1, String str2)
    Compares two CharSequences, returning `true` if they represent equal sequences of characters.

    `null`s are handled without exceptions. Two `null` references are considered to be equal.

    Case-sensitive examples

        Strings.CS.equals(null, null)   = true
        Strings.CS.equals(null, "abc")  = false
        Strings.CS.equals("abc", null)  = false
        Strings.CS.equals("abc", "abc") = true
        Strings.CS.equals("abc", "ABC") = false

    Case-insensitive examples

        Strings.CI.equals(null, null)   = true
        Strings.CI.equals(null, "abc")  = false
        Strings.CI.equals("abc", null)  = false
        Strings.CI.equals("abc", "abc") = true
        Strings.CI.equals("abc", "ABC") = true

    Parameters:
      `str1` - the first CharSequence, may be `null`
      `str2` - the second CharSequence, may be `null`
    Returns:
      `true` if the CharSequences are equal (case-sensitive), or both `null`
    See Also:
      - `Object.equals(Object)`
      - `String.compareTo(String)`
      - `String.equalsIgnoreCase(String)`

  - ### equalsAny

    public boolean equalsAny(CharSequence string, CharSequence... searchStrings)
    Compares given `string` to a CharSequences vararg of `searchStrings`, returning `true` if the `string` is equal to any of the `searchStrings`.

    Case-sensitive examples

        Strings.CS.equalsAny(null, (CharSequence[]) null) = false
        Strings.CS.equalsAny(null, null, null)    = true
        Strings.CS.equalsAny(null, "abc", "def")  = false
        Strings.CS.equalsAny("abc", null, "def")  = false
        Strings.CS.equalsAny("abc", "abc", "def") = true
        Strings.CS.equalsAny("abc", "ABC", "DEF") = false

    Case-insensitive examples

        Strings.CI.equalsAny(null, (CharSequence[]) null) = false
        Strings.CI.equalsAny(null, null, null)    = true
        Strings.CI.equalsAny(null, "abc", "def")  = false
        Strings.CI.equalsAny("abc", null, "def")  = false
        Strings.CI.equalsAny("abc", "abc", "def") = true
        Strings.CI.equalsAny("abc", "ABC", "DEF") = true

    Parameters:
      `string` - to compare, may be `null`.
      `searchStrings` - a vararg of strings, may be `null`.
    Returns:
      `true` if the string is equal (case-sensitive) to any other element of `searchStrings`; `false` if `searchStrings` is null or contains no matches.

  - ### indexOf

    public int indexOf(CharSequence seq, CharSequence searchSeq)
    Finds the first index within a CharSequence, handling `null`. This method uses `String.indexOf(String, int)` if possible.

    A `null` CharSequence will return `-1`.

    Case-sensitive examples

        Strings.CS.indexOf(null, *)          = -1
        Strings.CS.indexOf(*, null)          = -1
        Strings.CS.indexOf("", "")           = 0
        Strings.CS.indexOf("", *)            = -1 (except when * = "")
        Strings.CS.indexOf("aabaabaa", "a")  = 0
        Strings.CS.indexOf("aabaabaa", "b")  = 2
        Strings.CS.indexOf("aabaabaa", "ab") = 1
        Strings.CS.indexOf("aabaabaa", "")   = 0

    Case-insensitive examples

        Strings.CI.indexOf(null, *)          = -1
        Strings.CI.indexOf(*, null)          = -1
        Strings.CI.indexOf("", "")           = 0
        Strings.CI.indexOf(" ", " ")         = 0
        Strings.CI.indexOf("aabaabaa", "a")  = 0
        Strings.CI.indexOf("aabaabaa", "b")  = 2
        Strings.CI.indexOf("aabaabaa", "ab") = 1

    Parameters:
      `seq` - the CharSequence to check, may be null
      `searchSeq` - the CharSequence to find, may be null
    Returns:
      the first index of the search CharSequence, -1 if no match or `null` string input

  - ### indexOf

    public abstract int indexOf(CharSequence seq, CharSequence searchSeq, int startPos)
    Finds the first index within a CharSequence, handling `null`. This method uses `String.indexOf(String, int)` if possible.

    A `null` CharSequence will return `-1`. A negative start position is treated as zero. An empty ("") search CharSequence always matches. A start position greater than the string length only matches an empty search CharSequence.

    Case-sensitive examples

        Strings.CS.indexOf(null, *, *)          = -1
        Strings.CS.indexOf(*, null, *)          = -1
        Strings.CS.indexOf("", "", 0)           = 0
        Strings.CS.indexOf("", *, 0)            = -1 (except when * = "")
        Strings.CS.indexOf("aabaabaa", "a", 0)  = 0
        Strings.CS.indexOf("aabaabaa", "b", 0)  = 2
        Strings.CS.indexOf("aabaabaa", "ab", 0) = 1
        Strings.CS.indexOf("aabaabaa", "b", 3)  = 5
        Strings.CS.indexOf("aabaabaa", "b", 9)  = -1
        Strings.CS.indexOf("aabaabaa", "b", -1) = 2
        Strings.CS.indexOf("aabaabaa", "", 2)   = 2
        Strings.CS.indexOf("abc", "", 9)        = 3

    Case-insensitive examples

        Strings.CI.indexOf(null, *, *)          = -1
        Strings.CI.indexOf(*, null, *)          = -1
        Strings.CI.indexOf("", "", 0)           = 0
        Strings.CI.indexOf("aabaabaa", "A", 0)  = 0
        Strings.CI.indexOf("aabaabaa", "B", 0)  = 2
        Strings.CI.indexOf("aabaabaa", "AB", 0) = 1
        Strings.CI.indexOf("aabaabaa", "B", 3)  = 5
        Strings.CI.indexOf("aabaabaa", "B", 9)  = -1
        Strings.CI.indexOf("aabaabaa", "B", -1) = 2
        Strings.CI.indexOf("aabaabaa", "", 2)   = 2
        Strings.CI.indexOf("abc", "", 9)        = -1

    Parameters:
      `seq` - the CharSequence to check, may be null
      `searchSeq` - the CharSequence to find, may be null
      `startPos` - the start position, negative treated as zero
    Returns:
      the first index of the search CharSequence (always ≥ startPos), -1 if no match or `null` string input

  - ### isCaseSensitive

    public boolean isCaseSensitive()
    Tests whether to ignore case.
    Returns:
      whether to ignore case.

  - ### lastIndexOf

    public int lastIndexOf(CharSequence str, CharSequence searchStr)
    Finds the last index within a CharSequence, handling `null`. This method uses `String.lastIndexOf(String)` if possible.

    A `null` CharSequence will return `-1`.

    Case-sensitive examples

        Strings.CS.lastIndexOf(null, *)          = -1
        Strings.CS.lastIndexOf(*, null)          = -1
        Strings.CS.lastIndexOf("", "")           = 0
        Strings.CS.lastIndexOf("aabaabaa", "a")  = 7
        Strings.CS.lastIndexOf("aabaabaa", "b")  = 5
        Strings.CS.lastIndexOf("aabaabaa", "ab") = 4
        Strings.CS.lastIndexOf("aabaabaa", "")   = 8

    Case-insensitive examples

        Strings.CI.lastIndexOf(null, *)          = -1
        Strings.CI.lastIndexOf(*, null)          = -1
        Strings.CI.lastIndexOf("aabaabaa", "A")  = 7
        Strings.CI.lastIndexOf("aabaabaa", "B")  = 5
        Strings.CI.lastIndexOf("aabaabaa", "AB") = 4

    Parameters:
      `str` - the CharSequence to check, may be null
      `searchStr` - the CharSequence to find, may be null
    Returns:
      the last index of the search String, -1 if no match or `null` string input

  - ### lastIndexOf

    public abstract int lastIndexOf(CharSequence seq, CharSequence searchSeq, int startPos)
    Finds the last index within a CharSequence, handling `null`. This method uses `String.lastIndexOf(String, int)` if possible.

    A `null` CharSequence will return `-1`. A negative start position returns `-1`. An empty ("") search CharSequence always matches unless the start position is negative. A start position greater than the string length searches the whole string. The search starts at the startPos and works backwards; matches starting after the start position are ignored.

    Case-sensitive examples

        Strings.CS.lastIndexOf(null, *, *)          = -1
        Strings.CS.lastIndexOf(*, null, *)          = -1
        Strings.CS.lastIndexOf("aabaabaa", "a", 8)  = 7
        Strings.CS.lastIndexOf("aabaabaa", "b", 8)  = 5
        Strings.CS.lastIndexOf("aabaabaa", "ab", 8) = 4
        Strings.CS.lastIndexOf("aabaabaa", "b", 9)  = 5
        Strings.CS.lastIndexOf("aabaabaa", "b", -1) = -1
        Strings.CS.lastIndexOf("aabaabaa", "a", 0)  = 0
        Strings.CS.lastIndexOf("aabaabaa", "b", 0)  = -1
        Strings.CS.lastIndexOf("aabaabaa", "b", 1)  = -1
        Strings.CS.lastIndexOf("aabaabaa", "b", 2)  = 2
        Strings.CS.lastIndexOf("aabaabaa", "ba", 2)  = 2

    Case-insensitive examples

        Strings.CI.lastIndexOf(null, *, *)          = -1
        Strings.CI.lastIndexOf(*, null, *)          = -1
        Strings.CI.lastIndexOf("aabaabaa", "A", 8)  = 7
        Strings.CI.lastIndexOf("aabaabaa", "B", 8)  = 5
        Strings.CI.lastIndexOf("aabaabaa", "AB", 8) = 4
        Strings.CI.lastIndexOf("aabaabaa", "B", 9)  = 5
        Strings.CI.lastIndexOf("aabaabaa", "B", -1) = -1
        Strings.CI.lastIndexOf("aabaabaa", "A", 0)  = 0
        Strings.CI.lastIndexOf("aabaabaa", "B", 0)  = -1

    Parameters:
      `seq` - the CharSequence to check, may be null
      `searchSeq` - the CharSequence to find, may be null
      `startPos` - the start position, negative treated as zero
    Returns:
      the last index of the search CharSequence (always ≤ startPos), -1 if no match or `null` string input

  - ### prependIfMissing

    public String prependIfMissing(String str, CharSequence prefix, CharSequence... prefixes)
    Prepends the prefix to the start of the string if the string does not already start with any of the prefixes.

    Case-sensitive examples

        Strings.CS.prependIfMissing(null, null) = null
        Strings.CS.prependIfMissing("abc", null) = "abc"
        Strings.CS.prependIfMissing("", "xyz") = "xyz"
        Strings.CS.prependIfMissing("abc", "xyz") = "xyzabc"
        Strings.CS.prependIfMissing("xyzabc", "xyz") = "xyzabc"
        Strings.CS.prependIfMissing("XYZabc", "xyz") = "xyzXYZabc"

    With additional prefixes,

        Strings.CS.prependIfMissing(null, null, null) = null
        Strings.CS.prependIfMissing("abc", null, null) = "abc"
        Strings.CS.prependIfMissing("", "xyz", null) = "xyz"
        Strings.CS.prependIfMissing("abc", "xyz", new CharSequence[]{null}) = "xyzabc"
        Strings.CS.prependIfMissing("abc", "xyz", "") = "abc"
        Strings.CS.prependIfMissing("abc", "xyz", "mno") = "xyzabc"
        Strings.CS.prependIfMissing("xyzabc", "xyz", "mno") = "xyzabc"
        Strings.CS.prependIfMissing("mnoabc", "xyz", "mno") = "mnoabc"
        Strings.CS.prependIfMissing("XYZabc", "xyz", "mno") = "xyzXYZabc"
        Strings.CS.prependIfMissing("MNOabc", "xyz", "mno") = "xyzMNOabc"

    Case-insensitive examples

        Strings.CI.prependIfMissing(null, null) = null
        Strings.CI.prependIfMissing("abc", null) = "abc"
        Strings.CI.prependIfMissing("", "xyz") = "xyz"
        Strings.CI.prependIfMissing("abc", "xyz") = "xyzabc"
        Strings.CI.prependIfMissing("xyzabc", "xyz") = "xyzabc"
        Strings.CI.prependIfMissing("XYZabc", "xyz") = "XYZabc"

    With additional prefixes,

        Strings.CI.prependIfMissing(null, null, null) = null
        Strings.CI.prependIfMissing("abc", null, null) = "abc"
        Strings.CI.prependIfMissing("", "xyz", null) = "xyz"
        Strings.CI.prependIfMissing("abc", "xyz", new CharSequence[]{null}) = "xyzabc"
        Strings.CI.prependIfMissing("abc", "xyz", "") = "abc"
        Strings.CI.prependIfMissing("abc", "xyz", "mno") = "xyzabc"
        Strings.CI.prependIfMissing("xyzabc", "xyz", "mno") = "xyzabc"
        Strings.CI.prependIfMissing("mnoabc", "xyz", "mno") = "mnoabc"
        Strings.CI.prependIfMissing("XYZabc", "xyz", "mno") = "XYZabc"
        Strings.CI.prependIfMissing("MNOabc", "xyz", "mno") = "MNOabc"

    Parameters:
      `str` - The string.
      `prefix` - The prefix to prepend to the start of the string.
      `prefixes` - Additional prefixes that are valid.
    Returns:
      A new String if prefix was prepended, the same string otherwise.

  - ### remove

    public String remove(String str, String remove)
    Removes all occurrences of a substring from within the source string.

    A `null` source string will return `null`. An empty ("") source string will return the empty string. A `null` remove string will return the source string. An empty ("") remove string will return the source string.

    Case-sensitive examples

        Strings.CS.remove(null, *)        = null
        Strings.CS.remove("", *)          = ""
        Strings.CS.remove(*, null)        = *
        Strings.CS.remove(*, "")          = *
        Strings.CS.remove("queued", "ue") = "qd"
        Strings.CS.remove("queued", "zz") = "queued"

    Case-insensitive examples

        Strings.CI.remove(null, *)        = null
        Strings.CI.remove("", *)          = ""
        Strings.CI.remove(*, null)        = *
        Strings.CI.remove(*, "")          = *
        Strings.CI.remove("queued", "ue") = "qd"
        Strings.CI.remove("queued", "zz") = "queued"
        Strings.CI.remove("quEUed", "UE") = "qd"
        Strings.CI.remove("queued", "zZ") = "queued"

    Parameters:
      `str` - the source String to search, may be null
      `remove` - the String to search for and remove, may be null
    Returns:
      the substring with the string removed if found, `null` if null String input

  - ### removeEnd

    public String removeEnd(String str, CharSequence remove)
    Case-insensitive removal of a substring if it is at the end of a source string, otherwise returns the source string.

    A `null` source string will return `null`. An empty ("") source string will return the empty string. A `null` search string will return the source string.

    Case-sensitive examples

        Strings.CS.removeEnd(null, *)      = null
        Strings.CS.removeEnd("", *)        = ""
        Strings.CS.removeEnd(*, null)      = *
        Strings.CS.removeEnd("www.domain.com", ".com.")  = "www.domain.com"
        Strings.CS.removeEnd("www.domain.com", ".com")   = "www.domain"
        Strings.CS.removeEnd("www.domain.com", "domain") = "www.domain.com"
        Strings.CS.removeEnd("abc", "")    = "abc"

    Case-insensitive examples

        Strings.CI.removeEnd(null, *)      = null
        Strings.CI.removeEnd("", *)        = ""
        Strings.CI.removeEnd(*, null)      = *
        Strings.CI.removeEnd("www.domain.com", ".com.")  = "www.domain.com"
        Strings.CI.removeEnd("www.domain.com", ".com")   = "www.domain"
        Strings.CI.removeEnd("www.domain.com", "domain") = "www.domain.com"
        Strings.CI.removeEnd("abc", "")    = "abc"
        Strings.CI.removeEnd("www.domain.com", ".COM") = "www.domain")
        Strings.CI.removeEnd("www.domain.COM", ".com") = "www.domain")

    Parameters:
      `str` - the source String to search, may be null
      `remove` - the String to search for (case-insensitive) and remove, may be null
    Returns:
      the substring with the string removed if found, `null` if null String input

  - ### removeStart

    public String removeStart(String str, CharSequence remove)
    Case-insensitive removal of a substring if it is at the beginning of a source string, otherwise returns the source string.

    A `null` source string will return `null`. An empty ("") source string will return the empty string. A `null` search string will return the source string.

    Case-sensitive examples

        Strings.CS.removeStart(null, *)      = null
        Strings.CS.removeStart("", *)        = ""
        Strings.CS.removeStart(*, null)      = *
        Strings.CS.removeStart("www.domain.com", "www.")   = "domain.com"
        Strings.CS.removeStart("domain.com", "www.")       = "domain.com"
        Strings.CS.removeStart("www.domain.com", "domain") = "www.domain.com"
        Strings.CS.removeStart("abc", "")    = "abc"

    Case-insensitive examples

        Strings.CI.removeStart(null, *)      = null
        Strings.CI.removeStart("", *)        = ""
        Strings.CI.removeStart(*, null)      = *
        Strings.CI.removeStart("www.domain.com", "www.")   = "domain.com"
        Strings.CI.removeStart("www.domain.com", "WWW.")   = "domain.com"
        Strings.CI.removeStart("domain.com", "www.")       = "domain.com"
        Strings.CI.removeStart("www.domain.com", "domain") = "www.domain.com"
        Strings.CI.removeStart("abc", "")    = "abc"

    Parameters:
      `str` - the source String to search, may be null
      `remove` - the String to search for (case-insensitive) and remove, may be null
    Returns:
      the substring with the string removed if found, `null` if null String input

  - ### replace

    public String replace(String text, String searchString, String replacement)
    Case insensitively replaces all occurrences of a String within another String.

    A `null` reference passed to this method is a no-op.

    Case-sensitive examples

        Strings.CS.replace(null, *, *)        = null
        Strings.CS.replace("", *, *)          = ""
        Strings.CS.replace("any", null, *)    = "any"
        Strings.CS.replace("any", *, null)    = "any"
        Strings.CS.replace("any", "", *)      = "any"
        Strings.CS.replace("aba", "a", null)  = "aba"
        Strings.CS.replace("aba", "a", "")    = "b"
        Strings.CS.replace("aba", "a", "z")   = "zbz"

    Case-insensitive examples

        Strings.CI.replace(null, *, *)        = null
        Strings.CI.replace("", *, *)          = ""
        Strings.CI.replace("any", null, *)    = "any"
        Strings.CI.replace("any", *, null)    = "any"
        Strings.CI.replace("any", "", *)      = "any"
        Strings.CI.replace("aba", "a", null)  = "aba"
        Strings.CI.replace("abA", "A", "")    = "b"
        Strings.CI.replace("aba", "A", "z")   = "zbz"

    Parameters:
      `text` - text to search and replace in, may be null
      `searchString` - the String to search for (case-insensitive), may be null
      `replacement` - the String to replace it with, may be null
    Returns:
      the text with any replacements processed, `null` if null String input
    See Also:
      - `replace(String text, String searchString, String replacement, int max)`

  - ### replace

    public String replace(String text, String searchString, String replacement, int max)
    Replaces a String with another String inside a larger String, for the first `max` values of the search String.

    A `null` reference passed to this method is a no-op.

    Case-sensitive examples

        Strings.CS.replace(null, *, *, *)         = null
        Strings.CS.replace("", *, *, *)           = ""
        Strings.CS.replace("any", null, *, *)     = "any"
        Strings.CS.replace("any", *, null, *)     = "any"
        Strings.CS.replace("any", "", *, *)       = "any"
        Strings.CS.replace("any", *, *, 0)        = "any"
        Strings.CS.replace("abaa", "a", null, -1) = "abaa"
        Strings.CS.replace("abaa", "a", "", -1)   = "b"
        Strings.CS.replace("abaa", "a", "z", 0)   = "abaa"
        Strings.CS.replace("abaa", "a", "z", 1)   = "zbaa"
        Strings.CS.replace("abaa", "a", "z", 2)   = "zbza"
        Strings.CS.replace("abaa", "a", "z", -1)  = "zbzz"

    Case-insensitive examples

        Strings.CI.replace(null, *, *, *)         = null
        Strings.CI.replace("", *, *, *)           = ""
        Strings.CI.replace("any", null, *, *)     = "any"
        Strings.CI.replace("any", *, null, *)     = "any"
        Strings.CI.replace("any", "", *, *)       = "any"
        Strings.CI.replace("any", *, *, 0)        = "any"
        Strings.CI.replace("abaa", "a", null, -1) = "abaa"
        Strings.CI.replace("abaa", "a", "", -1)   = "b"
        Strings.CI.replace("abaa", "a", "z", 0)   = "abaa"
        Strings.CI.replace("abaa", "A", "z", 1)   = "zbaa"
        Strings.CI.replace("abAa", "a", "z", 2)   = "zbza"
        Strings.CI.replace("abAa", "a", "z", -1)  = "zbzz"

    Parameters:
      `text` - text to search and replace in, may be null
      `searchString` - the String to search for (case-insensitive), may be null
      `replacement` - the String to replace it with, may be null
      `max` - maximum number of values to replace, or `-1` if no maximum
    Returns:
      the text with any replacements processed, `null` if null String input

  - ### replaceOnce

    public String replaceOnce(String text, String searchString, String replacement)
    Replaces a String with another String inside a larger String, once.

    A `null` reference passed to this method is a no-op.

    Case-sensitive examples

        Strings.CS.replaceOnce(null, *, *)        = null
        Strings.CS.replaceOnce("", *, *)          = ""
        Strings.CS.replaceOnce("any", null, *)    = "any"
        Strings.CS.replaceOnce("any", *, null)    = "any"
        Strings.CS.replaceOnce("any", "", *)      = "any"
        Strings.CS.replaceOnce("aba", "a", null)  = "aba"
        Strings.CS.replaceOnce("aba", "a", "")    = "ba"
        Strings.CS.replaceOnce("aba", "a", "z")   = "zba"

    Case-insensitive examples

        Strings.CI.replaceOnce(null, *, *)        = null
        Strings.CI.replaceOnce("", *, *)          = ""
        Strings.CI.replaceOnce("any", null, *)    = "any"
        Strings.CI.replaceOnce("any", *, null)    = "any"
        Strings.CI.replaceOnce("any", "", *)      = "any"
        Strings.CI.replaceOnce("aba", "a", null)  = "aba"
        Strings.CI.replaceOnce("aba", "a", "")    = "ba"
        Strings.CI.replaceOnce("aba", "a", "z")   = "zba"
        Strings.CI.replaceOnce("FoOFoofoo", "foo", "") = "Foofoo"

    Parameters:
      `text` - text to search and replace in, may be null
      `searchString` - the String to search for, may be null
      `replacement` - the String to replace with, may be null
    Returns:
      the text with any replacements processed, `null` if null String input
    See Also:
      - `replace(String text, String searchString, String replacement, int max)`

  - ### startsWith

    public boolean startsWith(CharSequence str, CharSequence prefix)
    Tests if a CharSequence starts with a specified prefix.

    `null`s are handled without exceptions. Two `null` references are considered to be equal.

    Case-sensitive examples

        Strings.CS.startsWith(null, null)      = true
        Strings.CS.startsWith(null, "abc")     = false
        Strings.CS.startsWith("abcdef", null)  = false
        Strings.CS.startsWith("abcdef", "abc") = true
        Strings.CS.startsWith("ABCDEF", "abc") = false

    Case-insensitive examples

        Strings.CI.startsWith(null, null)      = true
        Strings.CI.startsWith(null, "abc")     = false
        Strings.CI.startsWith("abcdef", null)  = false
        Strings.CI.startsWith("abcdef", "abc") = true
        Strings.CI.startsWith("ABCDEF", "abc") = true

    Parameters:
      `str` - the CharSequence to check, may be null
      `prefix` - the prefix to find, may be null
    Returns:
      `true` if the CharSequence starts with the prefix, case-sensitive, or both `null`
    See Also:
      - `String.startsWith(String)`

  - ### startsWithAny

    public boolean startsWithAny(CharSequence sequence, CharSequence... searchStrings)
    Tests if a CharSequence starts with any of the provided prefixes.

    Case-sensitive examples

        Strings.CS.startsWithAny(null, null)      = false
        Strings.CS.startsWithAny(null, new String[] {"abc"})  = false
        Strings.CS.startsWithAny("abcxyz", null)     = false
        Strings.CS.startsWithAny("abcxyz", new String[] {""}) = true
        Strings.CS.startsWithAny("abcxyz", new String[] {"abc"}) = true
        Strings.CS.startsWithAny("abcxyz", new String[] {null, "xyz", "abc"}) = true
        Strings.CS.startsWithAny("abcxyz", null, "xyz", "ABCX") = false
        Strings.CS.startsWithAny("ABCXYZ", null, "xyz", "abc") = false

    Case-insensitive examples

        Strings.CI.startsWithAny(null, null)      = false
        Strings.CI.startsWithAny(null, new String[] {"aBc"})  = false
        Strings.CI.startsWithAny("AbCxYz", null)     = false
        Strings.CI.startsWithAny("AbCxYz", new String[] {""}) = true
        Strings.CI.startsWithAny("AbCxYz", new String[] {"aBc"}) = true
        Strings.CI.startsWithAny("AbCxYz", new String[] {null, "XyZ", "aBc"}) = true
        Strings.CI.startsWithAny("abcxyz", null, "xyz", "ABCX") = true
        Strings.CI.startsWithAny("ABCXYZ", null, "xyz", "abc") = true

    Parameters:
      `sequence` - the CharSequence to check, may be null
      `searchStrings` - the CharSequence prefixes, may be empty or contain `null`
    Returns:
      `true` if the input `sequence` is `null` AND no `searchStrings` are provided, or the input `sequence` begins with any of the provided `searchStrings`.
    See Also:
      - `startsWith(CharSequence, CharSequence)`