-2

I have a string, this string changes constantly.

I grab a part of my string which in code can be called let mySub = "xyz"

The original string is something that is changing over time, so dont worry how I get mySub for this example lets say the string is let baseString = 123123xyz1234

How would I be able to grab a substring of everything before xyz without it being hard coded so the position of xyz can be different and the substring grabbing still works correctly?

justADummy
  • 62
  • 1
  • 9

2 Answers2

2

You can find first matching range of mySub in baseString, and if found, get previous part.

let baseString: String = "123123xyz1234"
let mySub = "xyz"
if let range = baseString.range(of: mySub) {
    let beforeStr = baseString[..<range.lowerBound]
}
Omer Faruk Ozturk
  • 1,722
  • 13
  • 25
1

You can get the lowerbound index of the range of your substring and get the substring upTo that index. If you would like to make a caseInsensitive of diacritic insensitive search you can use localizedStandardRange:

extension StringProtocol  {
    func substring<S: StringProtocol>(upTo string: S, options: String.CompareOptions = []) -> SubSequence? {
        guard let lower = range(of: string, options: options)?.lowerBound
        else { return nil }
        return self[..<lower]
    }
    func localizedStandardSubstring<S: StringProtocol>(upTo string: S, options: String.CompareOptions = []) -> SubSequence? {
        guard let lower = localizedStandardRange(of: string)?.lowerBound
        else { return nil }
        return self[..<lower]
    }
}

let string = "123123xyz1234"
if let substring = string.substring(upTo: "xyz") {
    print(substring)  // "123123\n"
}

let localized = "123123café1234"
if let substring = localized.localizedStandardSubstring(upTo: "CAFE") {
    print(substring)  // "123123\n"
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571