How do I remove dashes, parentheses, and spaces from a phone number? [duplicate] - swift

Using only swift code I cant figure out how to take "(555) 555-5555" and return only the numeric values and get "5555555555". I need to remove all the parentheses, white spaces, and the dash. The only examples I can find are in objective-C and they seem to all use the .trim() method. It appears as though swift doesn't have this method but it does have the .stringByTrimmingCharacters method, but that only seems to trim the white spaces before and after the data.

Swift 3 & 4
extension String {
var digits: String {
return components(separatedBy: CharacterSet.decimalDigits.inverted)
.joined()
}
}
Swift 5
You should be able to omit return
Also:
Read the comment from #onmyway133 for a word of caution

Split the string by non-digit characters to an array of digits and the join them back to a string:
Swift 1:
let stringArray = origString.componentsSeparatedByCharactersInSet(
NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let newString = NSArray(array: stringArray).componentsJoinedByString("")
Swift 2:
let stringArray = origString.componentsSeparatedByCharactersInSet(
NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let newString = stringArray.joinWithSeparator("")
Swift 3 & 4:
let newString = origString
.components(separatedBy:CharacterSet.decimalDigits.inverted)
.joined()

I like regular expressions:
var s = "(555) 555-5555"
s = s.stringByReplacingOccurrencesOfString(
"\\D", withString: "", options: .RegularExpressionSearch,
range: s.startIndex..<s.endIndex)

In Swift 4 the solution is more nice:
import Foundation
let sourceText = "+5 (555) 555-5555"
let allowedCharset = CharacterSet
.decimalDigits
.union(CharacterSet(charactersIn: "+"))
let filteredText = String(sourceText.unicodeScalars.filter(allowedCharset.contains))
print(filteredText) // +55555555555

Here is #Tapani's Swift 2.0 answer as a handy String extension, (length property is not part of solution but I left it in example because it is also handy):
import Foundation
extension String {
var length : Int {
return self.characters.count
}
func digitsOnly() -> String{
let stringArray = self.componentsSeparatedByCharactersInSet(
NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let newString = stringArray.joinWithSeparator("")
return newString
}
}
Usage:
let phone = "(123)-123 - 1234"
print(phone.digitsOnly())

I had a similar issue but I needed to retain the decimal points. I tweaked the top answer to this:
extension String {
/// Returns a string with all non-numeric characters removed
public var numericString: String {
let characterSet = CharacterSet(charactersIn: "0123456789.").inverted
return components(separatedBy: characterSet)
.joined()
}
}

Details
Xcode Version 10.2.1 (10E1001), Swift 5
Solution
import Foundation
extension String {
private func filterCharacters(unicodeScalarsFilter closure: (UnicodeScalar) -> Bool) -> String {
return String(String.UnicodeScalarView(unicodeScalars.filter { closure($0) }))
}
private func filterCharacters(definedIn charSets: [CharacterSet], unicodeScalarsFilter: (CharacterSet, UnicodeScalar) -> Bool) -> String {
if charSets.isEmpty { return self }
let charSet = charSets.reduce(CharacterSet()) { return $0.union($1) }
return filterCharacters { unicodeScalarsFilter(charSet, $0) }
}
func removeCharacters(charSets: [CharacterSet]) -> String { return filterCharacters(definedIn: charSets) { !$0.contains($1) } }
func removeCharacters(charSet: CharacterSet) -> String { return removeCharacters(charSets: [charSet]) }
func onlyCharacters(charSets: [CharacterSet]) -> String { return filterCharacters(definedIn: charSets) { $0.contains($1) } }
func onlyCharacters(charSet: CharacterSet) -> String { return onlyCharacters(charSets: [charSet]) }
}
Usage
let string = "23f45gdor##%#i425v wer 24 1+DWEJwi 3u09ru49w*()9uE2R_)$I#Q)_ U383q04+RFJO{dgnkvlj b`kefl;nwdl qsa`WKFSA,.E"
print("original string: \(string)")
print("only .decimalDigits: \(string.onlyCharacters(charSet: .decimalDigits))")
print("only [.lowercaseLetters, .symbols]: \(string.onlyCharacters(charSets: [.lowercaseLetters, .symbols]))")
print("remove .letters: \(string.removeCharacters(charSet: .letters))")
print("remove [.decimalDigits, .lowercaseLetters]: \(string.removeCharacters(charSets: [.decimalDigits, .lowercaseLetters]))")
Result
original string: 23f45gdor##%#i425v wer 24 1+DWEJwi 3u09ru49w*()9uE2R_)$I#Q)_ U383q04+RFJO{dgnkvlj b`kefl;nwdl qsa`WKFSA,.E
only .decimalDigits: 2345425241309499238304
only [.lowercaseLetters, .symbols]: fgdorivwer+wiuruwu$q+dgnkvljb`keflnwdlqsa`
remove .letters: 2345##%#425 24 1+ 30949*()92_)$#)_ 38304+{ `; `,.
remove [.decimalDigits, .lowercaseLetters]: ##%# +DWEJ *()ER_)$I#Q)_ U+RFJO{ `; `WKFSA,.E
(Optional) String extension
extension String {
var onlyDigits: String { return onlyCharacters(charSets: [.decimalDigits]) }
var onlyLetters: String { return onlyCharacters(charSets: [.letters]) }
}
(Optional) String extension usage
let string = "23f45gdor##%#i425v wer 24 1+DWEJwi 3u09ru49w*()9uE2R_)$I#Q)_ U383q04+RFJO{dgnkvlj b`kefl;nwdl qsa`WKFSA,.E"
print("original string: \(string)")
print(".onlyDigits: \(string.onlyDigits)")
print(".onlyLetters: \(string.onlyLetters)")
(Optional) String extension usage result
original string: 23f45gdor##%#i425v wer 24 1+DWEJwi 3u09ru49w*()9uE2R_)$I#Q)_ U383q04+RFJO{dgnkvlj b`kefl;nwdl qsa`WKFSA,.E
.onlyDigits: 2345425241309499238304
.onlyLetters: fgdorivwerDWEJwiuruwuERIQUqRFJOdgnkvljbkeflnwdlqsaWKFSAE

Try this:
let string = "(555) 555-5555"
let digitString = string.filter { ("0"..."9").contains($0) }
print(digitString) // 5555555555
Putting in extension:
extension String
{
var digitString: String { filter { ("0"..."9").contains($0) } }
}
print("(555) 555-5555".digitString) // 5555555555

You'll want to use NSCharacterSet:
Check out this NSHipster link for Swift and Obj-C implementations:
http://nshipster.com/nscharacterset/
Similar example:
var string = " Lorem ipsum dolar sit amet. "
let components = string.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceCharacterSet()).filter({!isEmpty($0)})
string = join(" ", components)
See: punctuationCharacterSet
Description:
Returns a character set containing the characters in the category of Punctuation.
Informally, this set is the set of all non-whitespace characters used to separate linguistic units in scripts, such as periods, dashes, parentheses, and so on.
#Tapani Makes a great suggestion: NSCharacterSet.decimalDigitCharacterSet().invertedSet

Here is #Tapani Swift 3.2 solution
let phno = contact.phoneNumbers[0].phoneNumber
let strarr = phno.components(separatedBy: NSCharacterSet.decimalDigits.inverted)
let newString = NSArray(array: strarr).componentsJoined(by: "")
print(newString)

I found the best solution with filter function. Please have a look into it.
let string = "(555) 555-5555"
let onlyDigits = string.filter({ (char) -> Bool in
if Int("\(char)") != nil {
return true
}
else {
return false
}
})

Not exactly answered but it looks like a number.
I used URLComponents to build the url because it strips out parenthesis and dashes automatically:
var telUrl: URL? {
var component = URLComponents()
component.scheme = "tel"
component.path = "+49 (123) 1234 - 56789"
return component.url
}
then
UIApplication.shared.open(telUrl, options: [:], completionHandler: nil)
calls +49 123 123456789

Related

swift: how can I delete a specific character?

a string such as ! !! yuahl! ! , I want delete ! and , when I code like this
for index in InputName.characters.indices {
if String(InputName[index]) == "" || InputName.substringToIndex(index) == "!" {
InputName.removeAtIndex(index)
}
}
have this error " fatal error: subscript: subRange extends past String end ", how should I do? THX :D
Swift 5+
let myString = "aaaaaaaabbbb"
let replaced = myString.replacingOccurrences(of: "bbbb", with: "") // "aaaaaaaa"
If you need to remove characters only on both ends, you can use stringByTrimmingCharactersInSet(_:)
let delCharSet = NSCharacterSet(charactersInString: "! ")
let s1 = "! aString! !"
let s1Del = s1.stringByTrimmingCharactersInSet(delCharSet)
print(s1Del) //->aString
let s2 = "! anotherString !! aString! !"
let s2Del = s2.stringByTrimmingCharactersInSet(delCharSet)
print(s2Del) //->anotherString !! aString
If you need to remove characters also in the middle, "reconstruct from the filtered output" would be a little bit more efficient than repeating single character removal.
var tempUSView = String.UnicodeScalarView()
tempUSView.appendContentsOf(s2.unicodeScalars.lazy.filter{!delCharSet.longCharacterIsMember($0.value)})
let s2DelAll = String(tempUSView)
print(s2DelAll) //->anotherStringaString
If you don't mind generating many intermediate Strings and Arrays, this single liner can generate the expected output:
let s2DelAll2 = s2.componentsSeparatedByCharactersInSet(delCharSet).joinWithSeparator("")
print(s2DelAll2) //->anotherStringaString
I find that the filter method is a good way to go for this sort of thing:
let unfiltered = "! !! yuahl! !"
// Array of Characters to remove
let removal: [Character] = ["!"," "]
// turn the string into an Array
let unfilteredCharacters = unfiltered.characters
// return an Array without the removal Characters
let filteredCharacters = unfilteredCharacters.filter { !removal.contains($0) }
// build a String with the filtered Array
let filtered = String(filteredCharacters)
print(filtered) // => "yeah"
// combined to a single line
print(String(unfiltered.characters.filter { !removal.contains($0) })) // => "yuahl"
Swift 3
In Swift 3, the syntax is a bit nicer. As a result of the Great Swiftification of the old APIs, the factory method is now called trimmingCharacters(in:). Also, you can construct the CharacterSet as a Set of single-character Strings:
let string = "! !! yuahl! !"
string.trimmingCharacters(in: [" ", "!"]) // "yuahl"
If you have characters in the middle of the string you would like to remove as well, you can use components(separatedBy:).joined():
let string = "! !! yu !ahl! !"
string.components(separatedBy: ["!", " "]).joined() // "yuahl"
H/T #OOPer for the Swift 2 version
func trimLast(character chars: Set<Character>) -> String {
let str: String = String(self.reversed())
guard let index = str.index(where: {!chars.contains($0)}) else {
return self
}
return String((str[index..<str.endIndex]).reversed())
}
Note:
By adding this function in String extension, you can delete the specific character of string at last.
for index in InputName.characters.indices.reversed() {
if String(InputName[index]) == "" || InputName.substringToIndex(index) == "!" {
InputName.removeAtIndex(index)
}
}
Also you can add such very helpful extension :
import Foundation
extension String{
func exclude(find:String) -> String {
return stringByReplacingOccurrencesOfString(find, withString: "", options: .CaseInsensitiveSearch, range: nil)
}
func replaceAll(find:String, with:String) -> String {
return stringByReplacingOccurrencesOfString(find, withString: with, options: .CaseInsensitiveSearch, range: nil)
}
}
you can use this:
for example if you want to remove "%" the percent from 10%
if let i = text.firstIndex(of: "%") {
text.remove(at: i) //10
}

Remove all non-numeric characters from a string in swift

I have the need to parse some unknown data which should just be a numeric value, but may contain whitespace or other non-alphanumeric characters.
Is there a new way of doing this in Swift? All I can find online seems to be the old C way of doing things.
I am looking at stringByTrimmingCharactersInSet - as I am sure my inputs will only have whitespace/special characters at the start or end of the string. Are there any built in character sets I can use for this? Or do I need to create my own?
I was hoping there would be something like stringFromCharactersInSet() which would allow me to specify only valid characters to keep
I was hoping there would be something like stringFromCharactersInSet() which would allow me to specify only valid characters to keep.
You can either use trimmingCharacters with the inverted character set to remove characters from the start or the end of the string. In Swift 3 and later:
let result = string.trimmingCharacters(in: CharacterSet(charactersIn: "0123456789.").inverted)
Or, if you want to remove non-numeric characters anywhere in the string (not just the start or end), you can filter the characters, e.g. in Swift 4.2.1:
let result = string.filter("0123456789.".contains)
Or, if you want to remove characters from a CharacterSet from anywhere in the string, use:
let result = String(string.unicodeScalars.filter(CharacterSet.whitespaces.inverted.contains))
Or, if you want to only match valid strings of a certain format (e.g. ####.##), you could use regular expression. For example:
if let range = string.range(of: #"\d+(\.\d*)?"#, options: .regularExpression) {
let result = string[range] // or `String(string[range])` if you need `String`
}
The behavior of these different approaches differ slightly so it just depends on precisely what you're trying to do. Include or exclude the decimal point if you want decimal numbers, or just integers. There are lots of ways to accomplish this.
For older, Swift 2 syntax, see previous revision of this answer.
let result = string.stringByReplacingOccurrencesOfString("[^0-9]", withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range:nil).stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
Swift 3
let result = string.replacingOccurrences( of:"[^0-9]", with: "", options: .regularExpression)
You can upvote this answer.
I prefer this solution, because I like extensions, and it seems a bit cleaner to me. Solution reproduced here:
extension String {
var digits: String {
return components(separatedBy: CharacterSet.decimalDigits.inverted)
.joined()
}
}
You can filter the UnicodeScalarView of the string using the pattern matching operator for ranges, pass a UnicodeScalar ClosedRange from 0 to 9 and initialise a new String with the resulting UnicodeScalarView:
extension String {
private static var digits = UnicodeScalar("0")..."9"
var digits: String {
return String(unicodeScalars.filter(String.digits.contains))
}
}
"abc12345".digits // "12345"
edit/update:
Swift 4.2
extension RangeReplaceableCollection where Self: StringProtocol {
var digits: Self {
return filter(("0"..."9").contains)
}
}
or as a mutating method
extension RangeReplaceableCollection where Self: StringProtocol {
mutating func removeAllNonNumeric() {
removeAll { !("0"..."9" ~= $0) }
}
}
Swift 5.2 • Xcode 11.4 or later
In Swift5 we can use a new Character property called isWholeNumber:
extension RangeReplaceableCollection where Self: StringProtocol {
var digits: Self { filter(\.isWholeNumber) }
}
extension RangeReplaceableCollection where Self: StringProtocol {
mutating func removeAllNonNumeric() {
removeAll { !$0.isWholeNumber }
}
}
To allow a period as well we can extend Character and create a computed property:
extension Character {
var isDecimalOrPeriod: Bool { "0"..."9" ~= self || self == "." }
}
extension RangeReplaceableCollection where Self: StringProtocol {
var digitsAndPeriods: Self { filter(\.isDecimalOrPeriod) }
}
Playground testing:
"abc12345".digits // "12345"
var str = "123abc0"
str.removeAllNonNumeric()
print(str) //"1230"
"Testing0123456789.".digitsAndPeriods // "0123456789."
Swift 4
I found a decent way to get only alpha numeric characters set from a string.
For instance:-
func getAlphaNumericValue() {
var yourString = "123456789!##$%^&*()AnyThingYouWant"
let unsafeChars = CharacterSet.alphanumerics.inverted // Remove the .inverted to get the opposite result.
let cleanChars = yourString.components(separatedBy: unsafeChars).joined(separator: "")
print(cleanChars) // 123456789AnyThingYouWant
}
A solution using the filter function and rangeOfCharacterFromSet
let string = "sld [f]34é7*˜µ"
let alphaNumericCharacterSet = NSCharacterSet.alphanumericCharacterSet()
let filteredCharacters = string.characters.filter {
return String($0).rangeOfCharacterFromSet(alphaNumericCharacterSet) != nil
}
let filteredString = String(filteredCharacters) // -> sldf34é7µ
To filter for only numeric characters use
let string = "sld [f]34é7*˜µ"
let numericSet = "0123456789"
let filteredCharacters = string.characters.filter {
return numericSet.containsString(String($0))
}
let filteredString = String(filteredCharacters) // -> 347
or
let numericSet : [Character] = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
let filteredCharacters = string.characters.filter {
return numericSet.contains($0)
}
let filteredString = String(filteredCharacters) // -> 347
Swift 4
But without extensions or componentsSeparatedByCharactersInSet which doesn't read as well.
let allowedCharSet = NSCharacterSet.letters.union(.whitespaces)
let filteredText = String(sourceText.unicodeScalars.filter(allowedCharSet.contains))
let string = "+1*(234) fds567#-8/90-"
let onlyNumbers = string.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
print(onlyNumbers) // "1234567890"
or
extension String {
func removeNonNumeric() -> String {
return self.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
}
}
let onlyNumbers = "+1*(234) fds567#-8/90-".removeNonNumeric()
print(onlyNumbers)// "1234567890"
Swift 3, filters all except numbers
let myString = "dasdf3453453fsdf23455sf.2234"
let result = String(myString.characters.filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil })
print(result)
Swift 4.2
let numericString = string.filter { (char) -> Bool in
return char.isNumber
}
You can do something like this...
let string = "[,myString1. \"" // string : [,myString1. "
let characterSet = NSCharacterSet(charactersInString: "[,. \"")
let finalString = (string.componentsSeparatedByCharactersInSet(characterSet) as NSArray).componentsJoinedByString("")
print(finalString)
//finalString will be "myString1"
The issue with Rob's first solution is stringByTrimmingCharactersInSet only filters the ends of the string rather than throughout, as stated in Apple's documentation:
Returns a new string made by removing from both ends of the receiver characters contained in a given character set.
Instead use componentsSeparatedByCharactersInSet to first isolate all non-occurrences of the character set into arrays and subsequently join them with an empty string separator:
"$$1234%^56()78*9££".componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "0123456789").invertedSet)).joinWithSeparator("")
Which returns 123456789
Swift 3
extension String {
var keepNumericsOnly: String {
return self.components(separatedBy: CharacterSet(charactersIn: "0123456789").inverted).joined(separator: "")
}
}
Swift 4.0 version
extension String {
var numbers: String {
return String(describing: filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil })
}
}
Swift 4
String.swift
import Foundation
extension String {
func removeCharacters(from forbiddenChars: CharacterSet) -> String {
let passed = self.unicodeScalars.filter { !forbiddenChars.contains($0) }
return String(String.UnicodeScalarView(passed))
}
func removeCharacters(from: String) -> String {
return removeCharacters(from: CharacterSet(charactersIn: from))
}
}
ViewController.swift
let character = "1Vi234s56a78l9"
let alphaNumericSet = character.removeCharacters(from: CharacterSet.decimalDigits.inverted)
print(alphaNumericSet) // will print: 123456789
let alphaNumericCharacterSet = character.removeCharacters(from: "0123456789")
print("no digits",alphaNumericCharacterSet) // will print: Vishal
Swift 4.2
let digitChars = yourString.components(separatedBy:
CharacterSet.decimalDigits.inverted).joined(separator: "")
Swift 3 Version
extension String
{
func trimmingCharactersNot(in charSet: CharacterSet) -> String
{
var s:String = ""
for unicodeScalar in self.unicodeScalars
{
if charSet.contains(unicodeScalar)
{
s.append(String(unicodeScalar))
}
}
return s
}
}

Use filter() on a string in Swift 2

I'm not sure if the API in swift 2 changed, but I can't get filter to work on a string in Swift 2. The following should change "abc123$$$ ff" into "abcff".
// Removes all special characters and whitespaces
func compressString(aString: String) -> String{
let charSet = NSCharacterSet.letterCharacterSet()
// The following don't work:
// return aString.filter{charSet.contains($0)}
// return String(filter(aString).{charSet.contains($0)})
}
If you want to use filter, you need to run it on the characters view:
// Removes all special characters and whitespaces
func compressString(aString: String) -> String{
let charSet: [Character] = ["$", " ", "1", "2", "3"]
// The following don't work:
return String(aString.characters.filter { !charSet.contains($0) })
}
let before = "abc123$$$ ff"
let after = compressString(before) // "abcff"
func compressString(aString: String) -> String {
let letterSet = NSCharacterSet.letterCharacterSet()
return String(aString.characters.filter{letterSet.characterIsMember(String($0).utf16.first!)})
}
let str = "abc123$$$ ff"
compressString(str) // abcff
You can also create an extension to simplify your code:
extension String {
var lettersOnly: String {
return String(characters.filter{NSCharacterSet.letterCharacterSet().characterIsMember(String($0).utf16.first!)})
}
}
// Removes all special characters and whitespaces
let str = "abc123$$$ ff"
let letters = str.lettersOnly // "abcff"

How to capitalize the first character of sentence using Swift

I have a String description that holds my sentence and want to capitalize only the first letter. I tried different things but most of them give me exceptions and errors. I'm using Xcode 6.
Here is what I tried so far:
let cap = [description.substringToIndex(advance(0,1))] as String
description = cap.uppercaseString + description.substringFromIndex(1)
It gives me:
Type 'String.Index' does not conform to protocol 'IntegerLiteralConvertible'
I tried:
func capitalizedStringWithLocale(locale:0) -> String
But I haven't figured out how to make it work.
In Swift 2, you can do
String(text.characters.first!).capitalizedString + String(text.characters.dropFirst())
Another possibility in Swift 3:
extension String {
func capitalizeFirst() -> String {
let firstIndex = self.index(startIndex, offsetBy: 1)
return self.substring(to: firstIndex).capitalized + self.substring(from: firstIndex).lowercased()
}
}
For Swift 4:
Warnings from above Swift 3 code:
'substring(to:)' is deprecated: Please use String slicing subscript
with a 'partial range upto' operator.
'substring(from:)' is deprecated: Please use String slicing subscript with a 'partial range from' operator.
Swift 4 solution:
extension String {
var capitalizedFirst: String {
guard !isEmpty else {
return self
}
let capitalizedFirstLetter = charAt(i: 0).uppercased()
let secondIndex = index(after: startIndex)
let remainingString = self[secondIndex..<endIndex]
let capitalizedString = "\(capitalizedFirstLetter)\(remainingString)"
return capitalizedString
}
}
Swift 5.0
Answer 1:
extension String {
func capitalizingFirstLetter() -> String {
return prefix(1).capitalized + dropFirst()
}
mutating func capitalizeFirstLetter() {
self = self.capitalizingFirstLetter()
}
}
Answer 2:
extension String {
func capitalizeFirstLetter() -> String {
return self.prefix(1).capitalized + dropFirst()
}
}
Answer 3:
extension String {
var capitalizeFirstLetter:String {
return self.prefix(1).capitalized + dropFirst()
}
}
import Foundation
// A lowercase string
let description = "the quick brown fox jumps over the lazy dog."
// The start index is the first letter
let first = description.startIndex
// The rest of the string goes from the position after the first letter
// to the end.
let rest = advance(first,1)..<description.endIndex
// Glue these two ranges together, with the first uppercased, and you'll
// get the result you want. Note that I'm using description[first...first]
// to get the first letter because I want a String, not a Character, which
// is what you'd get with description[first].
let capitalised = description[first...first].uppercaseString + description[rest]
// Result: "The quick brown fox jumps over the lazy dog."
You may want to make sure there's at least one character in your sentence before you start, as otherwise you'll get a runtime error trying to advance the index beyond the end of the string.
Here is how to do it in Swift 4; just in case if it helps anybody:
extension String {
func captalizeFirstCharacter() -> String {
var result = self
let substr1 = String(self[startIndex]).uppercased()
result.replaceSubrange(...startIndex, with: substr1)
return result
}
}
It won't mutate the original String.
extension String {
var capitalizedFirstLetter:String {
let string = self
return string.replacingCharacters(in: startIndex...startIndex, with: String(self[startIndex]).capitalized)
}
}
Answer:
let newSentence = sentence.capitalizedFirstLetter
For one or each word in string, you can use String's .capitalized property.
print("foo".capitalized) //prints: Foo
print("foo foo foo".capitalized) //prints: Foo Foo Foo
Swift 4.2 version:
extension String {
var firstCharCapitalized: String {
switch count {
case 0:
return self
case 1:
return uppercased()
default:
return self[startIndex].uppercased() + self[index(after: startIndex)...]
}
}
}
Simplest soulution for Swift 4.0.
Add as a computed property extension:
extension String {
var firstCapitalized: String {
var components = self.components(separatedBy: " ")
guard let first = components.first else {
return self
}
components[0] = first.capitalized
return components.joined(separator: " ")
}
}
Usage:
"hello world".firstCapitalized

How to create String split extension with regex in Swift?

I wrote extension that create split method:
extension String {
func split(splitter: String) -> Array<String> {
return self.componentsSeparatedByString(splitter)
}
}
So in playground I can write:
var str = "Hello, playground"
if str.split(",").count > 1{
var out = str.split(",")[0]
println("output: \(out)") // output: Hello
}
What do I need to make it work with regex like in Java:
str.split("[ ]+")
Because this way it doesn't work.
Thanks,
First, your split function has some redundancy. It is enough to return
return self.componentsSeparatedByString(splitter)
Second, to work with a regular expression you just have to create a NSRegularExpression and then perhaps replace all occurrences with your own "stop string" and finally separate using that. E.g.
extension String {
func split(regex pattern: String) -> [String] {
let template = "-|*~~*~~*|-" /// Any string that isn't contained in the original string (self).
let regex = try? NSRegularExpression(pattern: pattern)
let modifiedString = regex?.stringByReplacingMatches(
in: self,
range: NSRange(
location: 0,
length: count
),
withTemplate: template /// Replace with the template/stop string.
)
/// Split by the replaced string.
return modifiedString?.components(separatedBy: template) ?? []
}
}