Swift: How to Get Everything After a Certain Set of Characters

Swift: How to get everything after a certain set of characters

In Swift 4, use upperBound and subscript operators and open range:

let snippet = "1111 West Main Street Beverly Hills, CA 90210 Phone: 123.456.7891"

if let range = snippet.range(of: "Phone: ") {
let phone = snippet[range.upperBound...]
print(phone) // prints "123.456.7891"
}

Or consider trimming the whitespace:

if let range = snippet.range(of: "Phone:") {
let phone = snippet[range.upperBound...].trimmingCharacters(in: .whitespaces)
print(phone) // prints "123.456.7891"
}

By the way, if you're trying to grab both at the same time, a regular expression can do that:

let snippet = "1111 West Main Street Beverly Hills, CA 90210 Phone: 123.456.7891"
let regex = try! NSRegularExpression(pattern: #"^(.*?)\s*Phone:\s*(.*)$"#, options: .caseInsensitive)
if let match = regex.firstMatch(in: snippet, range: NSRange(snippet.startIndex..., in: snippet)) {
let address = snippet[Range(match.range(at: 1), in: snippet)!]
let phone = snippet[Range(match.range(at: 2), in: snippet)!]
}

For prior versions of Swift, see previous revision of this answer.

How to get substring after last occurrence of character in string: Swift IOS

If you really want the characters after the last comma, you could use a regular expression:

let string = "Hamilton, A"
let regex = try! NSRegularExpression(pattern: ",\\s*(\\S[^,]*)$")
if let match = regex.firstMatch(in: string, range: string.nsRange), let result = string[match.range(at: 1)] {
// use `result` here
}

Where, in Swift 4:

extension String {

/// An `NSRange` that represents the full range of the string.

var nsRange: NSRange {
return NSRange(startIndex ..< endIndex, in: self)
}

/// Substring from `NSRange`
///
/// - Parameter nsRange: `NSRange` within the string.
/// - Returns: `Substring` with the given `NSRange`, or `nil` if the range can't be converted.

subscript(nsRange: NSRange) -> Substring? {
return Range(nsRange, in: self)
.flatMap { self[$0] }
}
}

Get the string up to a specific character

Expanding on @appzYourLife answer, the following will also trim off the whitespace characters after removing everything after the @ symbol.

import Foundation

var str = "hello, how are you @tom"

if str.contains("@") {
let endIndex = str.range(of: "@")!.lowerBound
str = str.substring(to: endIndex).trimmingCharacters(in: .whitespacesAndNewlines)
}
print(str) // Output - "hello, how are you"

UPDATE:

In response to finding the last occurance of the @ symbol in the string and removing it, here is how I would approach it:

var str = "hello, how are you @tom @tim?"
if str.contains("@") {
//Reverse the string
var reversedStr = String(str.characters.reversed())
//Find the first (last) occurance of @
let endIndex = reversedStr.range(of: "@")!.upperBound
//Get the string up to and after the @ symbol
let newStr = reversedStr.substring(from: endIndex).trimmingCharacters(in: .whitespacesAndNewlines)

//Store the new string over the original
str = String(newStr.characters.reversed())
//str = "hello, how are you @tom"
}

Or looking at @appzYourLife answer use range(of:options:range:locale:) instead of literally reversing the characters

var str = "hello, how are you @tom @tim?"
if str.contains("@") {
//Find the last occurrence of @
let endIndex = str.range(of: "@", options: .backwards, range: nil, locale: nil)!.lowerBound
//Get the string up to and after the @ symbol
let newStr = str.substring(from: endIndex).trimmingCharacters(in: .whitespacesAndNewlines)

//Store the new string over the original
str = newStr
//str = "hello, how are you @tom"
}

As an added bonus, here is how I would approach removing every @ starting with the last and working forward:

var str = "hello, how are you @tom and @tim?"
if str.contains("@") {

while str.contains("@") {
//Reverse the string
var reversedStr = String(str.characters.reversed())
//Find the first (last) occurance of @
let endIndex = reversedStr.range(of: "@")!.upperBound
//Get the string up to and after the @ symbol
let newStr = reversedStr.substring(from: endIndex).trimmingCharacters(in: .whitespacesAndNewlines)

//Store the new string over the original
str = String(newStr.characters.reversed())
}
//after while loop, str = "hello, how are you"
}

Delete all characters after a certain character from a string in Swift

You can use StringProtocol method range(of string:), get the resulting range lowerBound, create a PartialRangeUpTo with it and subscript the original string:

Swift 4 or later

let word = "orange"
if let index = word.range(of: "n")?.lowerBound {
let substring = word[..<index] // "ora"
// or let substring = word.prefix(upTo: index) // "ora"
// (see picture below) Using the prefix(upTo:) method is equivalent to using a partial half-open range as the collection’s subscript.
// The subscript notation is preferred over prefix(upTo:).

let string = String(substring)
print(string) // "ora"
}

Sample Image

Swift : How to get the string before a certain character?

Use componentsSeparatedByString() as shown below:

var delimiter = " "
var newstr = "token0 token1 token2 token3"
var token = newstr.components(separatedBy: delimiter)
print (token[0])

Or to use your specific case:

var delimiter = " token1"
var newstr = "token0 token1 token2 token3"
var token = newstr.components(separatedBy: delimiter)
print (token[0])

How to get a substring from a specific character to the end of the string in swift 4?

To answer your direct question: You can search for the last
occurrence of a string and get the substring from that position:

let path = "/Users/user/.../AppName/2017-07-07_21:14:52_0.jpeg"
if let r = path.range(of: "/", options: .backwards) {
let imageName = String(path[r.upperBound...])
print(imageName) // 2017-07-07_21:14:52_0.jpeg
}

(Code updated for Swift 4 and later.)

But what you really want is the "last path component" of a file path.
URL has the appropriate method for that purpose:

let path = "/Users/user/.../AppName/2017-07-07_21:14:52_0.jpeg"
let imageName = URL(fileURLWithPath: path).lastPathComponent
print(imageName) // 2017-07-07_21:14:52_0.jpeg

Removing everything between a certain set of characters with Swift

You can create a function to do it for you as follow:

func html2String(html:String) -> String {
return NSAttributedString(data: html.dataUsingEncoding(NSUTF8StringEncoding)!, options:[NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute:NSUTF8StringEncoding], documentAttributes: nil, error: nil)!.string
}

or as an extension:

extension String {
var html2String:String {
return NSAttributedString(data: dataUsingEncoding(NSUTF8StringEncoding)!, options: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute:NSUTF8StringEncoding], documentAttributes: nil, error: nil)!.string
}
var html2NSAttributedString:NSAttributedString {
return NSAttributedString(data: dataUsingEncoding(NSUTF8StringEncoding)!, options: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute:NSUTF8StringEncoding], documentAttributes: nil, error: nil)!
}
}

you might prefer as a NSData extension

extension NSData{
var htmlString:String {
return NSAttributedString(data: self, options: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute:NSUTF8StringEncoding], documentAttributes: nil, error: nil)!.string
}
}

or NSData as a function:

func html2String(html:NSData)-> String {
return NSAttributedString(data: html, options: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute:NSUTF8StringEncoding], documentAttributes: nil, error: nil)!.string
}

Usage:

"<div>Testing<br></div><a href=\"http://stackoverflow.com/questions/27661722/removing-everything-between-a-certain-set-of-characters-with-swift/27662573#27662573\"><span> Hello World !!!</span>".html2String  //  "Testing\n Hello World !!!"

let result = html2String("<div>Testing<br></div><a href=\"http://stackoverflow.com/questions/27661722/removing-everything-between-a-certain-set-of-characters-with-swift/27662573#27662573\"><span> Hello World !!!</span>") // "Testing\n Hello World !!!"

// lets load this html as String

import UIKit

class ViewController: UIViewController {
let questionLink = "http://stackoverflow.com/questions/27661722/removing-everything-between-a-certain-set-of-characters-with-swift/27662573#27662573"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if let questionUrl = NSURL(string: questionLink) {
println("LOADING URL")
if let myHtmlDataFromUrl = NSData(contentsOfURL: questionUrl){
println(myHtmlDataFromUrl.htmlString)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Swift 4.2 extract substring using multiple characters are delimiter

• Possible solution:

1. Separate all the elements (separator: white space)

2. Iterate 2 by 2 and use a key/value system, like a Dictionary.

3. Read each values from the keys afterward

Step 1:

let string = "A.1 value1 B.2 value2 E value3 C value4"
let components = string.components(separatedBy: CharacterSet.whitespaces)

Step 2:

var dictionary: [String: String] = [:]
stride(from: 0, to: components.count - 1, by: 2).forEach({
dictionary[components[$0]] = components[$0+1]
})

or

let dictionary = stride(from: 0, to: components.count - 1, by: 2).reduce(into: [String: String]()) { (result, currentInt) in 
result[components[currentInt]] = components[currentInt+1]
}

dictionary is ["A.1": "value1", "C": "value4", "E": "value3", "B.2": "value2"]

Inspiration for the stride(from:to:) that I rarely use.

Step 3:

let name = dictionary["A.1"]
let surname = dictionary["C"]

• Potential issues:

If you have:

let string = "A.1 value One B.2 value2 E value3 C value4"

You want "value One", and since there is a space, you'll get some issue because if will give a false result (since there is the separator).
You'll get: ["A.1": "value", "One": "B.2", "value2": "E", "value3": "C"] for dictionary.

So you could use instead a regex: A.1(.*)B.2(.*)E(.*)C(.*) (for instance).

let string = "A.1 value One B.2 value2 E value3 C value4"
let regex = try! NSRegularExpression(pattern: "A.1(.*)B.2(.*)E(.*)C(.*)", options: [])

regex.enumerateMatches(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count)) { (result, flags, stop) in
guard let result = result,
let aValueRange = Range(result.range(at: 1), in: string),
let bValueRange = Range(result.range(at: 2), in: string),
let cValueRange = Range(result.range(at: 4), in: string),
let eValueRange = Range(result.range(at: 3), in: string) else { return }
let aValue = string[aValueRange].trimmingCharacters(in: CharacterSet.whitespaces)
print("aValue: \(aValue)")
let bValue = string[bValueRange].trimmingCharacters(in: CharacterSet.whitespaces)
print("bValue: \(bValue)")
let cValue = string[cValueRange].trimmingCharacters(in: CharacterSet.whitespaces)
print("cValue: \(cValue)")
let eValue = string[eValueRange].trimmingCharacters(in: CharacterSet.whitespaces)
print("eValue: \(eValue)")

}

Output:

$>aValue: value One
$>bValue: value2
$>cValue: value4
$>eValue: value3

Note that the trim could be inside the regex, but I don't especially like having too complex regexes.

Get Length of a substring in string before certain character Swift


⚠️ Be aware of using replacingOccurrences!

Although this method (mentioned by @Raja Kishan) may work in some cases, it's not forward compatible and will fail if you have unhandled characters (like other expression operators)



✅ Just write it as you say it:

let numbers = "90000+8000-1000*10".split { !$0.isWholeNumber && $0 != "." }

You have the numbers! go ahead and count the length

numbers[0].count // show 5
numbers[1].count // shows 4


You can also have the operators like:

let operators = "90000+8000-1000*10".split { $0.isWholeNumber || $0 == "." }

How to Get and Set a string's character at a specific index in Swift

Depending on how many times you need to do this, it's probably best to just create a character array from the string, and index into that.

You can either do it for just the string you care about:

let strings = ["abcdefg", "123", "qwerty"]
let characters = Array(strings[1].characters) // => ["1", "2", "3"]
print(characters[0]) // => "1"

or if you'll be doing lots of accesses to all of the strings, you can preemptively turn all strings into [Character] in advance, like so:

let strings = ["abcdefg", "123", "qwerty"]
let stringCharacters = strings.map{ Array(string.characters) }
/* [
["a", "b", "c", "d", "e", "f", "g"],
["1", "2", "3"],
["q", "w", "e", "r", "t", "y"]
] */
print(characters[1][0]) // => "1"

If you want to make a change, then simply convert the character array back into a String, and assign it wherever you want it:

var strings = ["abcdefg", "123", "qwerty"]
var characters = Array(strings[1].characters) // => ["1", "2", "3"]
characters[0] = "0"
strings[1] = String(characters)
print(strings) // => ["abcdefg", "023", "qwerty"]

Also, here's a handy extension I use for mutating many characters of a string:

extension String {
mutating func modifyCharacters(_ closure: (inout [Character]) -> Void) {
var characterArray = Array(self.characters)
closure(&characterArray)
self = String(characterArray)
}
}


var string = "abcdef"

string.modifyCharacters {
$0[0] = "1"
$0[1] = "2"
$0[2] = "3"
}

print(string)


Related Topics



Leave a reply



Submit