Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Index of a substring in a string with Swift

I'm used to do this in JavaScript:

var domains = "abcde".substring(0, "abcde".indexOf("cd")) // Returns "ab" 

Swift doesn't have this function, how to do something similar?

like image 315
Armand Grillet Avatar asked Aug 31 '15 07:08

Armand Grillet


People also ask

How do you find the substring index of a string?

Java String indexOf() Method The indexOf() method returns the position of the first occurrence of specified character(s) in a string. Tip: Use the lastIndexOf method to return the position of the last occurrence of specified character(s) in a string.

How do you find the index of an element in a string in Swift?

In swift, we can use the firstIndex(of:) method to get the index position of a character in a given string.

Can you index a string in Swift?

If you don't have a String , though, then you can't construct a String. Index (because Swift can only calculate the index if it knows what the previous characters in the string are). If you change the string then you must recalculate the index. You can't use the same String.

How do you check if a string contains a substring in Swift?

To check if a string contains another string, we can use the built-in contains() method in Swift. The contains() method takes the string as an argument and returns true if a substring is found in the string; otherwise it returns false .


2 Answers

edit/update:

Xcode 11.4 • Swift 5.2 or later

import Foundation  extension StringProtocol {     func index<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> Index? {         range(of: string, options: options)?.lowerBound     }     func endIndex<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> Index? {         range(of: string, options: options)?.upperBound     }     func indices<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> [Index] {         ranges(of: string, options: options).map(\.lowerBound)     }     func ranges<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> [Range<Index>] {         var result: [Range<Index>] = []         var startIndex = self.startIndex         while startIndex < endIndex,             let range = self[startIndex...]                 .range(of: string, options: options) {                 result.append(range)                 startIndex = range.lowerBound < range.upperBound ? range.upperBound :                     index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex         }         return result     } } 

usage:

let str = "abcde" if let index = str.index(of: "cd") {     let substring = str[..<index]   // ab     let string = String(substring)     print(string)  // "ab\n" } 

let str = "Hello, playground, playground, playground" str.index(of: "play")      // 7 str.endIndex(of: "play")   // 11 str.indices(of: "play")    // [7, 19, 31] str.ranges(of: "play")     // [{lowerBound 7, upperBound 11}, {lowerBound 19, upperBound 23}, {lowerBound 31, upperBound 35}] 

case insensitive sample

let query = "Play" let ranges = str.ranges(of: query, options: .caseInsensitive) let matches = ranges.map { str[$0] }   // print(matches)  // ["play", "play", "play"] 

regular expression sample

let query = "play" let escapedQuery = NSRegularExpression.escapedPattern(for: query) let pattern = "\\b\(escapedQuery)\\w+"  // matches any word that starts with "play" prefix  let ranges = str.ranges(of: pattern, options: .regularExpression) let matches = ranges.map { str[$0] }  print(matches) //  ["playground", "playground", "playground"] 
like image 163
Leo Dabus Avatar answered Sep 21 '22 18:09

Leo Dabus


Using String[Range<String.Index>] subscript you can get the sub string. You need starting index and last index to create the range and you can do it as below

let str = "abcde" if let range = str.range(of: "cd") {   let substring = str[..<range.lowerBound] // or str[str.startIndex..<range.lowerBound]   print(substring)  // Prints ab } else {   print("String not present") } 

If you don't define the start index this operator ..< , it take the starting index. You can also use str[str.startIndex..<range.lowerBound] instead of str[..<range.lowerBound]

like image 34
Inder Kumar Rathore Avatar answered Sep 17 '22 18:09

Inder Kumar Rathore