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"
}
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
Swiftui: Is There Exist Modifier to Highlight Substring of Text() View
How to Embed Third Party Framework on Ionic Capacitor Custom Plugin
How to Speed Up Updating Relationship Among Tables, After One or Both Tables Are Already Saved
Swiftui: How to Make a Button Open a Url in Safari
Swift Can't Infer Generic Type When Generic Type Is Being Passed Through a Parameter
Missing Argument for Parameter 'From' in Call When Creating Instance of Codable Class
How to Handle Two Different Types in an Array in Swift for a Uitableview
Swift, Sprite Kit Game: Have Circle Disappear in Clockwise Manner? on Timer
Swift & Firebase - How to Store More User Data Other Than Email and Password
Wkwebview Auto Fill Login Form Swift 2
Create View Based Nstableview Programmatically Using Bindings in Swift