Home > Back-end >  How to get part of string before and after certain characters in Swift?
How to get part of string before and after certain characters in Swift?

Time:01-22

So I know there are other similar questions but they either relate to arrays or a different case of strings. Let's say I have the following string "AABBCCDDEEFF". How can I get everything after BB and before EE so I get an output of CCDD?

CodePudding user response:

String has a method called localizedStandardRange which is diacritic and case insensitive. You can get the range upper bound of the first match and search the substring after that index for the second match. If found you just need to check if the indices are not equal which would mean the result would be an empty string:

let string = "AABBCCDDEEFF"

if let start = string.localizedStandardRange(of: "Bb")?.upperBound,
   let end = string[start...].localizedStandardRange(of: "eE")?.lowerBound,
    start != end {
    let substring = string[start..<end]
    print(substring)   //  "CCDD\n"
}

CodePudding user response:

There are many regex options:

  1. In iOS 16 and later (or macOS 13 and later):

    let string = "AABBCCDDEEFF"
    
    guard let result = string.firstMatch(of: /BB(.*)EE/)?.1 else { return }
    print(result)
    
  2. Also in iOS 16 and later, if you're not comfortable with regex, you can use RegexBuilder:

    import RegexBuilder
    
    let regex = Regex {
        "BB"
        Capture { ZeroOrMore { CharacterClass.any } }
        "EE"
    }
    guard let result = string.firstMatch(of: regex)?.1 else { return }
    print(result)
    
  3. In older OS versions, you can use a variety of legacy regular expression approaches. E.g., you can look for a regular expression with look-behind and look-ahead assertions:

    guard let range = string.range(of: "(?<=BB).*(?=EE)", options: .regularExpression) else { return }
    print(string[range])
    
  4. Or, an even older technique is NSRegularExpression and perhaps a simple capture group:

    let regex = try! NSRegularExpression(pattern: "BB(.*)EE")
    guard
        let match = regex.firstMatch(in: string, range: NSRange(location: 0, length: string.utf16.count)),
        let range = Range(match.range(at: 1), in: string)
    else { return }
    print(string[range])
    

For the first two options, you can refer to WWDC 2022 videos Meet Swift Regex or Swift Regex: Beyond the basics

  • Related