How to remove all the spaces and \n\r in a String? - ios

What is the most efficient way to remove all the spaces, \n and \r in a String in Swift?
I have tried:
for character in string.characters {
}
But it's a little inconvenient.

Swift 4:
let text = "This \n is a st\tri\rng"
let test = String(text.filter { !" \n\t\r".contains($0) })
Output:
print(test) // Thisisastring
While Fahri's answer is nice, I prefer it to be pure Swift ;)

edit/update:
Swift 5.2 or later
We can use the new Character property isWhitespace
let textInput = "Line 1 \n Line 2 \n\r"
let result = textInput.filter { !$0.isWhitespace }
result // "Line1Line2"
extension StringProtocol where Self: RangeReplaceableCollection {
var removingAllWhitespaces: Self {
filter(\.isWhitespace.negated)
}
mutating func removeAllWhitespaces() {
removeAll(where: \.isWhitespace)
}
}
extension Bool {
var negated: Bool { !self }
}
let textInput = "Line 1 \n Line 2 \n\r"
let result = textInput.removingAllWhitespaces //"Line1Line2"
var test = "Line 1 \n Line 2 \n\r"
test.removeAllWhitespaces()
print(test) // "Line1Line2"
Note: For older Swift versions syntax check edit history

For the sake of completeness this is the Regular Expression version
let string = "What is the most efficient way to remove all the spaces and \n \r \tin a String in Swift"
let stringWithoutWhitespace = string.replacingOccurrences(of: "\\s", with: "", options: .regularExpression)
// -> "WhatisthemostefficientwaytoremoveallthespacesandinaStringinSwift"

For Swift 4:
let myString = "This \n is a st\tri\rng"
let trimmedString = myString.components(separatedBy: .whitespacesAndNewlines).joined()

If by spaces you mean whitespaces, be aware that more than one whitespace character exists, although they all look the same.
The following solution takes that into account:
Swift 5:
extension String {
func removingAllWhitespaces() -> String {
return removingCharacters(from: .whitespaces)
}
func removingCharacters(from set: CharacterSet) -> String {
var newString = self
newString.removeAll { char -> Bool in
guard let scalar = char.unicodeScalars.first else { return false }
return set.contains(scalar)
}
return newString
}
}
let noNewlines = "Hello\nWorld".removingCharacters(from: .newlines)
print(noNewlines)
let noWhitespaces = "Hello World".removingCharacters(from: .whitespaces)
print(noWhitespaces)

Use this:
let aString: String = "This is my string"
let newString = aString.stringByReplacingOccurrencesOfString(" ", withString: "", options:[], range: nil)
print(newString)
Output :
Thisismystring

If anyone is wondering why, despite of putting "\n" and "\r" into the set, "\r\n" is not removed from the string, it's because "\r\n" is treated by swift as one character.
Swift 4:
let text = "\r\n This \n is a st\tri\rng"
let test = String(text.filter { !"\r\n\n\t\r".contains($0) })
"\n" is not duplicated by accident

Suppose that you have this string : "some words \nanother word\n\r here something \tand something like \rmdjsbclsdcbsdilvb \n\rand finally this :)"
here the how to remove all possible space :
let possibleWhiteSpace:NSArray = [" ","\t", "\n\r", "\n","\r"] //here you add other types of white space
var string:NSString = "some words \nanother word\n\r here something \tand something like \rmdjsbclsdcbsdilvb \n\rand finally this :)"
print(string)// initial string with white space
possibleWhiteSpace.enumerateObjectsUsingBlock { (whiteSpace, idx, stop) -> Void in
string = string.stringByReplacingOccurrencesOfString(whiteSpace as! String, withString: "")
}
print(string)//resulting string
Let me know if this respond to your question :)

Swift 4:
let string = "Test\n with an st\tri\rng"
print(string.components(separatedBy: .whitespacesAndNewlines))
// Result: "Test with an string"

I just use this:
stringValue.replacingOccurrences(of: " ", with: "").replacingOccurrences(of: "\n", with: "")

Swift 4:
let text = "This \n is a st\tri\rng"
let cleanedText = text.filter { !" \n\t\r".characters.contains($0) }

Related

how to select specific words from an string of character

I am having a line like this
#aman#ab179#167#abbash aman battra
I want output like this
#aman
#ab179
#167
#abbash
All the characters having # as first letter but I am getting the whole line instead.
This is my code
for word in stringWordsArray {
print(word)
if word.hasPrefix("#"){
print("Exists")
print(word)
}
}
I guess, you were looking for split method of String. Here I have written example for you:
let str = "aman#ab179#167#abbash aman battra"
let separator = "#"
var arr = str
.split(separator: Character(separator)) // get array of string separated by `#`
.map { separator + $0 }// manually add `#`
.flatMap { $0.split(separator: " ").first } // remove substring separated by " "
print(arr)
This works:
let sentence = "#aman#ab179#167#abbash aman battra"
let words = sentence.split(separator: "#").flatMap { $0.split(separator: " ").first }.map { "#" + $0 }
Try this Code
let str = "aman#ab179#167#abbash aman battra"
let arr = str.components(separatedBy: "#")
for arrayString in arr{
print("\((String (describing: arrayString).firstWord()!))")
}
// for choose first word
extension String {
func firstWord() -> String? {
return self.components(separatedBy: " ").first
}
}
As per your requirement you will get exact output using below code
Swift 4.0
let temp = "#aman#ab179#167#abbash aman battra"
var fullNameArr = temp.components(separatedBy: .whitespaces)[0].split(separator: "#")
var arrData = [String]()
for word in fullNameArr {
var temp = word
temp.insert("#", at: temp.startIndex)
arrData.append(String(temp))
}
print(arrData)

Remove Last Two Characters in a String

Is there a quick way to remove the last two characters in a String in Swift? I see there is a simple way to remove the last character as clearly noted here. Do you know how to remove the last two characters? Thanks!
update: Xcode 9 • Swift 4 or later
String now conforms to RangeReplaceableCollection so you can use collection method dropLast straight in the String and therefore an extension it is not necessary anymore. The only difference is that it returns a Substring. If you need a String you need to initialize a new one from it:
let string = "0123456789"
let substring1 = string.dropLast(2) // "01234567"
let substring2 = substring1.dropLast() // "0123456"
let result = String(substring2.dropLast()) // "012345"
We can also extend LosslessStringConvertible to add trailing syntax which I think improves readability:
extension LosslessStringConvertible {
var string: String { .init(self) }
}
Usage:
let result = substring.dropLast().string
var name: String = "Dolphin"
let endIndex = name.index(name.endIndex, offsetBy: -2)
let truncated = name.substring(to: endIndex)
print(name) // "Dolphin"
print(truncated) // "Dolph"
swift 4:
let str = "Hello, playground"
let newSTR1 = str.dropLast(3)
print(newSTR1)
output: "Hello, playgro"
//---------------//
let str = "Hello, playground"
let newSTR2 = str.dropFirst(2)
print(newSTR2)
output: "llo, playground"
Use removeSubrange(Range<String.Index>) just like:
var str = "Hello, playground"
str.removeSubrange(Range(uncheckedBounds: (lower: str.index(str.endIndex, offsetBy: -2), upper: str.endIndex)))
This will crash if the string is less than 2 characters long. Is that a requirement for you?
Better to use removeLast()
var myString = "Hello world"
myString.removeLast(2)
output : "Hello wor"

How to get the first character of each word in a string?

I want this:
var String1 = "Stack Over Flow"
var desiredOutPut = "SOF" // the first Character of each word in a single String (after space)
I know how to get the first character from a string but have no idea what to do this with this problem.
You can try this code:
let stringInput = "First Last"
let stringInputArr = stringInput.components(separatedBy:" ")
var stringNeed = ""
for string in stringInputArr {
stringNeed += String(string.first!)
}
print(stringNeed)
If have problem with componentsSeparatedByString you can try seperate by character space and continue in array you remove all string empty.
Hope this help!
To keep it more elegant I would make an extension for the swift 3.0 String class with the following code.
extension String
{
public func getAcronyms(separator: String = "") -> String
{
let acronyms = self.components(separatedBy: " ").map({ String($0.characters.first!) }).joined(separator: separator);
return acronyms;
}
}
Afterwords you can just use it like this:
let acronyms = "Hello world".getAcronyms();
//will print: Hw
let acronymsWithSeparator = "Hello world".getAcronyms(separator: ".");
//will print: H.w
let upperAcronymsWithSeparator = "Hello world".getAcronyms(separator: ".").uppercased();
//will print: H.W
SWIFT 3
To avoid the crash when there are multiple spaces between words (i.e. John Smith), you can use something like this:
extension String {
func acronym() -> String {
return self.components(separatedBy: .whitespaces).filter { !$0.isEmpty }.reduce("") { $0.0 + String($0.1.characters.first!) }
}
}
If you want to include newlines as well, just replace .whitespaces with .whitespacesAndNewlines.
Or by using .reduce():
let str = "Stack Over Flow"
let desiredOutPut = str
.components(separatedBy: " ")
.reduce("") { $0 + ($1.first.map(String.init) ?? "") }
print(desiredOutPut)
Note that if you're experiencing error:
Cannot invoke 'reduce' with an argument list of type '(String, (_) -> _)
labelForContext.text = self.components(separatedBy: " ").reduce("") { first, next in
(first) + (next.first.map { String($0) } ?? "")
}
You can use the componentsSeparatedByString() method to get an array of strings. Use " " as the separator.
Since you know how to get the first char of a string, now you just do that for each string in the array.
var String1 = "Stack Over Flow"
let arr = String1.componentsSeparatedByString(" ")
var desiredoutput = ""
for str in arr {
if let char = str.characters.first {
desiredoutput += String(char)
}
}
desiredoutput
By the way, the convention for variable names I believe is camel-case with a lowercase letter for the first character, such as "string1" as opposed to "String1"
Here is the changes in swift3
let stringInput = "Stack Overflow"
let stringInputArr = stringInput.components(separatedBy: " ")
var stringNeed = ""
for string in stringInputArr {
stringNeed = stringNeed + String(string.characters.first!)
}
print(stringNeed)
For the sake of completeness this is a solution with very powerful enumerateSubstrings(in:options:_:
let string = "Stack Over Flow"
var result = ""
string.enumerateSubstrings(in: string.startIndex..<string.endIndex, options: .byWords) { (substring, _, _, _) in
if let substring = substring { result += substring.prefix(1) }
}
print(result)
let inputString = "ABC PQR XYZ"
var stringNeed = ""
class something
{
let splits = inputString.components(separatedBy: " ")
for string in splits
{
stringNeed = stringNeed + String(string.first!)
}
print(stringNeed)
}
Here's the version I used for Swift 5.7 and newer
extension String {
func getAcronym() -> String {
let array = components(separatedBy: .whitespaces)
return array.reduce("") { $0 + String($1.first!)}
}
}

How can I remove or replace all punctuation characters from a String?

I have a string composed of words, some of which contain punctuation, which I would like to remove, but I have been unable to figure out how to do this.
For example if I have something like
var words = "Hello, this : is .. a string?"
I would like to be able to create an array with
"[Hello, this, is, a, string]"
My original thought was to use something like words.stringByTrimmingCharactersInSet() to remove any characters I didn't want but that would only take characters off the ends.
I thought maybe I could iterate through the string with something in the vein of
for letter in words {
if NSCharacterSet.punctuationCharacterSet.characterIsMember(letter){
//remove that character from the string
}
}
but I'm unsure how to remove the character from the string. I'm sure there are some problems with the way that if statement is set up, as well, but it shows my thought process.
Xcode 11.4 • Swift 5.2 or later
extension StringProtocol {
var words: [SubSequence] {
split(whereSeparator: \.isLetter.negation)
}
}
extension Bool {
var negation: Bool { !self }
}
let sentence = "Hello, this : is .. a string?"
let words = sentence.words // ["Hello", "this", "is", "a", "string"]
String has a enumerateSubstringsInRange() method.
With the .ByWords option, it detects word boundaries and
punctuation automatically:
Swift 3/4:
let string = "Hello, this : is .. a \"string\"!"
var words : [String] = []
string.enumerateSubstrings(in: string.startIndex..<string.endIndex,
options: .byWords) {
(substring, _, _, _) -> () in
words.append(substring!)
}
print(words) // [Hello, this, is, a, string]
Swift 2:
let string = "Hello, this : is .. a \"string\"!"
var words : [String] = []
string.enumerateSubstringsInRange(string.characters.indices,
options: .ByWords) {
(substring, _, _, _) -> () in
words.append(substring!)
}
print(words) // [Hello, this, is, a, string]
This works with Xcode 8.1, Swift 3:
First define general-purpose extension for filtering by CharacterSet:
extension String {
func removingCharacters(inCharacterSet forbiddenCharacters:CharacterSet) -> String
{
var filteredString = self
while true {
if let forbiddenCharRange = filteredString.rangeOfCharacter(from: forbiddenCharacters) {
filteredString.removeSubrange(forbiddenCharRange)
}
else {
break
}
}
return filteredString
}
}
Then filter using punctuation:
let s:String = "Hello, world!"
s.removingCharacters(inCharacterSet: CharacterSet.punctuationCharacters) // => "Hello world"
let charactersToRemove = NSCharacterSet.punctuationCharacterSet().invertedSet
let aWord = "".join(words.componentsSeparatedByCharactersInSet(charactersToRemove))
An alternate way to filter characters from a set and obtain an array of words is by using the array's filter and reduce methods. It's not as compact as other answers, but it shows how the same result can be obtained in a different way.
First define an array of the characters to remove:
let charactersToRemove = Set(Array(".:?,"))
next convert the input string into an array of characters:
let arrayOfChars = Array(words)
Now we can use reduce to build a string, obtained by appending the elements from arrayOfChars, but skipping all the ones included in charactersToRemove:
let filteredString = arrayOfChars.reduce("") {
let str = String($1)
return $0 + (charactersToRemove.contains($1) ? "" : str)
}
This produces a string without the punctuation characters (as defined in charactersToRemove).
The last 2 steps:
split the string into an array of words, using the blank character as separator:
let arrayOfWords = filteredString.componentsSeparatedByString(" ")
last, remove all empty elements:
let finalArrayOfWords = arrayOfWords.filter { $0.isEmpty == false }
NSScaner way:
let words = "Hello, this : is .. a string?"
//
let scanner = NSScanner(string: words)
var wordArray:[String] = []
var word:NSString? = ""
while(!scanner.atEnd) {
var sr = scanner.scanCharactersFromSet(NSCharacterSet(charactersInString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKMNOPQRSTUVWXYZ"), intoString: &word)
if !sr {
scanner.scanLocation++
continue
}
wordArray.append(String(word!))
}
println(wordArray)

Swift Replace Multiple Characters in String

Below is the following line of code I use to replace an HTML break tag with a carriage return. However, I have other HTML symbols that I need to replace and when I call this line of code again, with different parameters, it's as if the first one is overwritten. Is there a way I can include multiple parameters? Is there a more efficient way to do this in Swift? For example: replace both br> with "" and nbsp with "".
textView.text = content.stringByReplacingOccurrencesOfString("<br /><br />", withString:"\r")
Use replacingOccurrences along with a the String.CompareOptions.regularExpresion option.
Example (Swift 3):
var x = "<Hello, [play^ground+]>"
let y = x.replacingOccurrences(of: "[\\[\\]^+<>]", with: "7", options: .regularExpression, range: nil)
print(y)
Input characters which are to be replaced inside the square brackets like so [\\ Characters]
Output:
7Hello, 7play7ground777
I solved it based on the idea of Rosetta Code
extension String {
func stringByRemovingAll(characters: [Character]) -> String {
return String(self.characters.filter({ !characters.contains($0) }))
}
func stringByRemovingAll(subStrings: [String]) -> String {
var resultString = self
subStrings.map { resultString = resultString.stringByReplacingOccurrencesOfString($0, withString: "") }
return resultString
}
}
Example:
let str = "Hello, stackoverflow"
let chars: [Character] = ["a", "e", "i"]
let myStrings = ["Hello", ", ", "overflow"]
let newString = str.stringByRemovingAll(chars)
let anotherString = str.stringByRemovingAll(myStrings)
Result, when printed:
newString: Hllo, stckovrflow
anotherString: stack
As #matt mentioned you are starting over with the same content string. The stringByReplacingOccurrencesOfString method doesn't actually change anything in the original content string. It returns to you a new string with the replacement changes while content remains unchanged.
Something like this should work for you
let result1 = content.stringByReplacingOccurrencesOfString("<br /><br />", withString:"\r")
let result2 = result1.stringByReplacingOccurrencesOfString(" ", withString:" ")
textView.text = result2
extension String {
var html2AttributedString:NSAttributedString {
return NSAttributedString(data: dataUsingEncoding(NSUTF8StringEncoding)!, options:[NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: NSUTF8StringEncoding], documentAttributes: nil, error: nil)!
}
}
let myHtmlCode = "<style type=\"text/css\">#red{color:#F00}#green{color:#0F0}#blue{color: #00F}</style><span id=\"red\" >Red</span> <span id=\"green\" >Green</span><span id=\"blue\">Blue</span>"
myHtmlCode.html2AttributedString

Resources