How to get the first characters in a string? (Swift 3) - swift

I want to get a substring out of a string which starts with either "<ONLINE>" or "<OFFLINE>" (which should become my substring). When I try to create a Range object, I can easily access the the first character by using startIndex but how do I get the index of the closing bracket of my substring which will be either the 8th or 9th character of the full string?
UPDATE:
A simple example:
let onlineString:String = "<ONLINE> Message with online tag!"
let substring:String = // Get the "<ONLINE> " part from my string?
let onlineStringWithoutTag:String = onlineString.replaceOccurances(of: substring, with: "")
// What I should get as the result: "Message with online tag!"
So basically, the question is: what do I do for substring?

let name = "Ajay"
// Use following line to extract first chracter(In String format)
print(name.characters.first?.description ?? "");
// Output : "A"

If you did not want to use range
let onlineString:String = "<ONLINE> Message with online tag!"
let substring:String = onlineString.components(separatedBy: " ")[0]
print(substring) // <ONLINE>

The correct way would be to use indexes as following:
let string = "123 456"
let firstCharIndex = string.index(string.startIndex, offsetBy: 1)
let firstChar = string.substring(to: firstCharIndex)
print(firstChar)

This Code provides you the first character of the string.
Swift provides this method which returns character? you have to wrap it before use
let str = "FirstCharacter"
print(str.first!)

Similar to OOPer's:
let string = "<ONLINE>"
let closingTag = CharacterSet(charactersIn: ">")
if let closingTagIndex = string.rangeOfCharacter(from: closingTag) {
let mySubstring = string.substring(with: string.startIndex..<closingTagIndex.upperBound)
}
Or with regex:
let string = "<ONLINE>jhkjhkh>"
if let range = string.range(of: "<[A-Z]+>", options: .regularExpression) {
let mySubstring = string.substring(with: range)
}

This code be some help for your purpose:
let myString = "<ONLINE>abc"
if let rangeOfClosingAngleBracket = myString.range(of: ">") {
let substring = myString.substring(to: rangeOfClosingAngleBracket.upperBound)
print(substring) //-><ONLINE>
}

Swift 4
let firstCharIndex = oneGivenName.index(oneGivenName.startIndex, offsetBy: 1)
let firstChar = String(oneGivenName[..<firstCharIndex])

let character = MyString.first
it's an simple way to get first character from string in swift.

In swift 5
let someString = "Stackoverflow"
let firstChar = someString.first?.description ?? ""
print(firstChar)

Swift 5 extension
extension String {
var firstCharactor: String? {
guard self.count > 0 else {
return nil
}
return String(self.prefix(1))
}
}

Related

Convert String to Postal code Format in swift

In App i have string like
1A11A1
I want to convert it to
1A1 1A1
There should be space after 3characters.
What i tried is : code = 1A11A1
let end = code.index(code.startIndex, offsetBy: code.count)
let range = code.startIndex..<end
if code.count < 3 {
code = code.replacingOccurrences(of: "(\\d+)", with: "$1", options: .regularExpression, range: range)
}
else {
code = code.replacingOccurrences(of: "(\\d{3})(\\d+)", with: "$1 $2", options: .regularExpression, range: range)
}
If your rule is that you want a "space after 3 characters," take three characters, add a space and then the rest:
let result = "\(code.prefix(3)) \(code.dropFirst(3))"
// "1A1 1A1"
Rob's solution is fine, just for the sake of it, there's also an option to use insert(" ", at: index), something like this:
extension String {
var postalCode: String {
var result = self
// Check that this string is the right length
guard result.count == 6 else {
return result
}
let index = result.index(result.startIndex, offsetBy: 3)
result.insert(" ", at: index)
return result
}
}
Test:
let str: String = "1A11A1"
print(str.postalCode) // prints 1A1 1A1
let str2: String = "1A1 1A1"
print(str2.postalCode) // prints 1A1 1A1 (doesn't change format)
let str3: String = "12345"
print(str3.postalCode) // prints 12345 (doesn't change format)

How to trim first 3 character from a string in swift

I have a dropdown(userCphList) in which there are 2 value : 66/001/0004, 66/002/9765. I want to trim the selected value of dropdown from 66/001/0004 to 001/0004.
Given below is my code:
userCphList.didSelect{(selectedText , index ,id) in
let cphid = selectedText
let url = self.appDelegate.BaseUrl + "geojson/proj_4326?cph_id=" + cphid
self.get_wl_geojsondata(url: url)
}
I want to get cphid as 001/0004.
Any help will be highly appreciated!
Thank You!
Rutuparna Panda
You can split your string where separator is a slash, drop the first component and then join it again:
let str = "66/001/0004"
let trimmed = str.split { $0 == "/" }
.dropFirst()
.joined(separator: "/") // "001/0004"
Another option is to find the first slash index and get the substring after it:
if let index = str.firstIndex(of: "/") {
let trimmed = str[str.index(after: index)...] // "001/0004"
// or simply dropping the first character
// let trimmed = str[index...].dropFirst()
}
If the number of characters to be dropped is fixed the easiest way is dropFirst
let string = "66/001/0004"
let trimmedString = String(string.dropFirst(3))
Other ways are Regular Expression
let trimmedString = string.replacingOccurrences(of: "^\\d+/", with: "", options: .regularExpression)
and removing the substring by range
if let range = string.range(of: "/") {
let trimmedString = String(string[range.upperBound...])
}

How to get specific string after and before specific character in swift?

I have this string: "lat/lng: (-6.2222391,106.7035684)"
I only need to get those double data type in that string. so how to get just only *-6.222239*1 and 106.7035684 as string variable?
How to get the number in that parenthesis?
So I think I have get string after "(" and before "," to get "-6.2222391" and also after "," and before ")" to get "106.7035684"
but I don't know how to get that in code
let source = "lat/lng: (-6.2222391,106.7035684)"
let splited = source.components(separatedBy: "lat/lng: ")[1] //separating
let removed = splited.replacingOccurrences(of: "(", with: "").replacingOccurrences(of: ")", with: "") // removing
let coord = removed.components(separatedBy: ",") // removing
let lat = Double(coord[0])
let lng = Double(coord[1])
You could use a regex:
let str = "lat/lng: (-6.2222391,106.7035684)"
let rg = NSRange(location: 0, length: (str as NSString).length)
let latRegex = try! NSRegularExpression(pattern: "(?<=\\()[+-\\.0-9]+(?=,)")
(?<=\\() is positive lookbehind, it looks for anything preceded by (,
[+-\\.0-9]+ eagerly looks for at least one character or more that are either +, -, ., or a digit from 0 to 9,
(?=,) is positive lookahead, it matches anything followed by ,.
Now let's use this regular expression :
let latitude: Double? = latRegex.matches(in: str, range: rg)
.compactMap { Double(str[Range($0.range, in: str)!]) }
.first
if let lat = latitude {
print(lat) //-6.2222391
}
In the same way, we can get the longitude :
let longRegex = try! NSRegularExpression(pattern: "(?<=,)[+-\\.0-9]+(?=\\))")
let longitude: Double? = longRegex.matches(in: str, range: rg)
.compactMap { Double(str[Range($0.range, in: str)!]) }
.first
if let long = longitude {
print(long) //106.7035684
}
PS: I've used forced unwrapping here and there for brevity
You have received some good answers already. But I think I've come up with a more compact version.
You need to care about - 0~9 . and ,
The , will be considered only for having the two components and then be used for separating them.
See this:
let source = "lat/lng: (-6.2222391,106.7035684)"
let allowedCharactersString = "-01234567890.,"
let latLongValues = String(source.characters.filter {
allowedCharactersString.characters.contains($0)
}).components(separatedBy: ",")
print(latLongValues.first!) // "-6.2222391"
print(latLongValues.last!) // "106.7035684"
Try this:
let source = "lat/lng: (-6.2222391,106.7035684)".components(separatedBy: ")")[0]
let removed = source.components(separatedBy: "(")[1];// removing
//OR
//let source = "lat/lng: (-6.2222391,106.7035684)".components(separatedBy: "(")[1]
//let removed = source.components(separatedBy: ")")[0];// removing
let coord = removed.components(separatedBy: ",") // removing
let lat = Double(coord[0])
let lng = Double(coord[1])

How to get substring with specific ranges in Swift 4?

This is using the example code from the official Swift4 doc
let greeting = "Hi there! It's nice to meet you! 👋"
let endOfSentence = greeting.index(of: "!")!
let firstSentence = greeting[...endOfSentence]
// firstSentence == "Hi there!"
But lets say let greeting = "Hello there world!"
and I want to retrieve only the second word (substring) in this sentence? So I only want the word "there".
I've tried using "world!" as an argument like
let endOfSentence = greeting.index(of: "world!")! but Swift 4 Playground doesn't like that. It's expecting 'Character' and my argument is a string.
So how can I get a substring of a very precise subrange? Or get nth word in a sentence for greater use in the future?
You can search for substrings using range(of:).
import Foundation
let greeting = "Hello there world!"
if let endIndex = greeting.range(of: "world!")?.lowerBound {
print(greeting[..<endIndex])
}
outputs:
Hello there
EDIT:
If you want to separate out the words, there's a quick-and-dirty way and a good way. The quick-and-dirty way:
import Foundation
let greeting = "Hello there world!"
let words = greeting.split(separator: " ")
print(words[1])
And here's the thorough way, which will enumerate all the words in the string no matter how they're separated:
import Foundation
let greeting = "Hello there world!"
var words: [String] = []
greeting.enumerateSubstrings(in: greeting.startIndex..<greeting.endIndex, options: .byWords) { substring, _, _, _ in
if let substring = substring {
words.append(substring)
}
}
print(words[1])
EDIT 2: And if you're just trying to get the 7th through the 11th character, you can do this:
import Foundation
let greeting = "Hello there world!"
let startIndex = greeting.index(greeting.startIndex, offsetBy: 6)
let endIndex = greeting.index(startIndex, offsetBy: 5)
print(greeting[startIndex..<endIndex])
For swift4,
let string = "substring test"
let start = String.Index(encodedOffset: 0)
let end = String.Index(encodedOffset: 10)
let substring = String(string[start..<end])
In Swift 5 encodedOffset (swift 4 func) is deprecated.
You will need to use utf160Offset
// Swift 5
let string = "Hi there! It's nice to meet you!"
let startIndex = 10 // random for this example
let endIndex = string.count
let start = String.Index(utf16Offset: startIndex, in: string)
let end = String.Index(utf16Offset: endIndex, in: string)
let substring = String(string[start..<end])
prints -> It's nice to meet you!
There is one mistake in the first answer.
Range<String.Index>.upperBound
The upperBound property should be the endIndex
For Example:
let text = "From Here Hello World"
if let result = text.range(of: "Hello World") {
let startIndex = result.upperBound
let endIndex = result.lowerBound
print(String(text[startIndex..<endIndex])) //"Hello World"
}
the simplest way I use is :
var str = "abcdefg"
String(Array(str)[2...4])
Old habits die hard. I did it the "Java" way and split the string up by spaces, then accessed the second word.
print(greeting.split(separator: " ")[1]) // "there /n"

How to filter non-digits from string

My phone numbers are like +7 (777) 777-7777.
I need only digits and plus symbol: +77777777777 to make calls.
This returns only digits:
let stringArray = origString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let newString = NSArray(array: stringArray).componentsJoinedByString("")
One of the many ways to do that:
let isValidCharacter: (Character) -> Bool = {
($0 >= "0" && $0 <= "9") || $0 == "+"
}
let newString = String(origString.characters.filter(isValidCharacter))
or using a regular expression:
// not a +, not a number
let pattern = "[^+0-9]"
// replace anything that is not a + and not a number with an empty string
let newString = origString.replacingOccurrences(
of: pattern,
with: "",
options: .regularExpression
)
or, if you really want to use your original solution with a character set.
let validCharacters = CharacterSet(charactersIn: "0123456789+")
let newString = origString
.components(separatedBy: validCharacters.inverted)
.joined()
In keeping with the spirit of your partial solution,
let origString:NSString = "+7 (777) 777-7777"
let cs = NSCharacterSet(charactersIn: "0123456789+")
let final = origString.components(separatedBy: cs.inverted).joined()