I have a huge text in String.
For example "... value=word. ...". How can I get the string "word" if I know that before I have "value=" and after "."?
for example:
for str in string {
if str == "value=" {
// then get the strings until .
}
}
Thanks!
You can extend String with a kind of sliceBetween method:
import Foundation
extension String {
func sliceFrom(start: String, to: String) -> String? {
guard let s = rangeOfString(start)?.endIndex else { return nil }
guard let e = rangeOfString(to, range: s..<endIndex)?.startIndex else { return nil }
return self[s..<e]
}
}
And you'd use it like this:
"... value=word. ...".sliceFrom("value=", to: ". ") // "word"
NSRegularExpression should solve your issue.
In order to use it, you will need to understand Regex first. In your case, you can use value=[\\w]+[^.]+ as your regex pattern.
The following code will give you a [String] object contains value=allCharacterBeforeFirstPeriod
let regex = try NSRegularExpression(pattern: "value=[\\w]+[^.]+", options: [])
let nsStr = str as NSString
let array = regex.matchesInString(str, options: [], range: NSMakeRange(0, nsStr.length))
let results = array.map({ nsStr.substringWithRange($0.range) })
And then if you only need the value after value=, you can use another map function to do it:
results.map({ $0.stringByReplacingOccurrencesOfString("value=", withString: "") })
I have tested the code with a 10,000 characters String. It finishes in ~0.3 sec
The most straight forward way to do this would be to use NSRegularExpression. Tutorial
Given an input String like this
let text = "key0=value0&key1=value1&key2=value2"
You can organireduce method
let dict = text.characters.split("&").reduce([String:String]()) { (var result, keyValue) -> [String:String] in
let chunks = keyValue.split("=")
guard let first = chunks.first, last = chunks.last else { return result }
let key = String(first)
let value = String(last)
result[key] = value
return result
}
Now everything is stored inside dict and you can easily access it
dict["key2"] // "value2"
Given a string, how do I truncate all characters following one particular character?
For example I have a url:
http://pics.v6.top.rbk.ru/v6_top_pics/resized/250xH/media/img/7/92/754435534528927.jpg"><div>Some text</div>"
I want to strip all characters after the ", including the " character.
extension String {
mutating func stripFromCharacter(char:String) {
let c = self.characters
if let ix = c.indexOf("\"") {
self = String(c.prefixUpTo(ix))
}
}
}
And here's how to use it:
var s = "http://pics.v6.top.rbk.ru/v6_top_pics/resized/250xH/media/img/7/92/754435534528927.jpg\"><div>Some text</div>"
s.stripFromCharacter("\"")
Probably the dumbest way to do it but it works.
let a = "http://pics.v6.top.rbk.ru/v6_top_pics/resized/250xH/media/img/7/92/754435534528927.jpg\"" + "><div>Some text</div>"
print(a)
var new = ""
for char in a.characters{
if char == "\""{ break }
new.append(char)
}
print(new)
Maybe you simply want to use NSDataDetectors?
E.G. something like:
let input = "http://pics.v6.top.rbk.ru/v6_top_pics/resized/250xH/media/img/7/92/754435534528927.jpg"><div>Some text</div>""
let detector = try! NSDataDetector(types: NSTextCheckingType.Link.rawValue)
let matches = detector.matchesInString(input, options: [], range: NSMakeRange(0, input.characters.count))
for match in matches {
let url = (input as NSString).substringWithRange(match.range)
print(url)
}
More info can be found in this HackingWithSwift blog post.
I need to know if a string contains an Int to be sure that a name the user entered is a valid full name,
for that I need to either make the user type only chars, or valid that there are no ints in the string the user entered.
Thanks for all the help.
You can use Foundation methods with Swift strings, and that's what you should do here. NSString has built in methods that use NSCharacterSet to check if certain types of characters are present. This translates nicely to Swift:
var str = "Hello, playground1"
let decimalCharacters = CharacterSet.decimalDigits
let decimalRange = str.rangeOfCharacter(from: decimalCharacters)
if decimalRange != nil {
print("Numbers found")
}
If you're interested in restricting what can be typed, you should implement UITextFieldDelegate and the method textField(_:shouldChangeCharactersIn:replacementString:) to prevent people from typing those characters in the first place.
Simple Swift 4 version using rangeOfCharacter method from String class:
let numbersRange = stringValue.rangeOfCharacter(from: .decimalDigits)
let hasNumbers = (numbersRange != nil)
This method is what i use now for checking if a string contains a number
func doStringContainsNumber( _string : String) -> Bool{
let numberRegEx = ".*[0-9]+.*"
let testCase = NSPredicate(format:"SELF MATCHES %#", numberRegEx)
let containsNumber = testCase.evaluateWithObject(_string)
return containsNumber
}
If your string Contains a number it will return true else false. Hope it helps
//Swift 3.0 to check if String contains numbers (decimal digits):
let someString = "string 1"
let numberCharacters = NSCharacterSet.decimalDigits
if someString.rangeOfCharacter(from: numberCharacters) != nil
{ print("String contains numbers")}
else if someString.rangeOfCharacter(from: numberCharacters) == nil
{ print("String doesn't contains numbers")}
//A function that checks if a string has any numbers
func stringHasNumber(_ string:String) -> Bool {
for character in string{
if character.isNumber{
return true
}
}
return false
}
/// Check stringHasNumber function
stringHasNumber("mhhhldiddld")
stringHasNumber("kjkdjd99900")
if (ContainsNumbers(str).count > 0)
{
// Your string contains at least one number 0-9
}
func ContainsNumbers(s: String) -> [Character]
{
return s.characters.filter { ("0"..."9").contains($0)}
}
Swift 2.3. version working.
extension String
{
func containsNumbers() -> Bool
{
let numberRegEx = ".*[0-9]+.*"
let testCase = NSPredicate(format:"SELF MATCHES %#", numberRegEx)
return testCase.evaluateWithObject(self)
}
}
Usage:
//guard let firstname = textField.text else { return }
let testStr1 = "lalalala"
let testStr2 = "1lalalala"
let testStr3 = "lal2lsd2l"
print("Test 1 = \(testStr1.containsNumbers())\nTest 2 = \(testStr2.containsNumbers())\nTest 3 = \(testStr3.containsNumbers())\n")
You need to trick Swift into using Regex by wrapping up its nsRegularExpression
class Regex {
let internalExpression: NSRegularExpression
let pattern: String
init(_ pattern: String) {
self.pattern = pattern
var error: NSError?
self.internalExpression = NSRegularExpression(pattern: pattern, options: .CaseInsensitive, error: &error)
}
func test(input: String) -> Bool {
let matches = self.internalExpression.matchesInString(input, options: nil, range:NSMakeRange(0, countElements(input)))
return matches.count > 0
}
}
if Regex("\\d/").test("John 2 Smith") {
println("has a number in the name")
}
I got these from http://benscheirman.com/2014/06/regex-in-swift/
let numericCharSet = CharacterSet.init(charactersIn: "1234567890")
let newCharSet = CharacterSet.init(charactersIn: "~`##$%^&*(){}[]<>?")
let sentence = "Tes#ting4 #Charact2er1Seqt"
if sentence.rangeOfCharacter(from: numericCharSet) != nil {
print("Yes It,Have a Numeric")
let removedSpl = sentence.components(separatedBy: newCharSet).joined()
print(sentence.components(separatedBy: newCharSet).joined())
print(removedSpl.components(separatedBy: numericCharSet).joined())
}
else {
print("No")
}
I need a way to remove the first character from a string which is a space. I am looking for a method or even an extension for the String type that I can use to cut out a character of a string.
To remove leading and trailing whitespaces:
let trimmedString = string.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
Swift 3 / Swift 4:
let trimmedString = string.trimmingCharacters(in: .whitespaces)
The correct way when you want to remove all kinds of whitespaces (based on this SO answer) is:
extension String {
var stringByRemovingWhitespaces: String {
let components = componentsSeparatedByCharactersInSet(.whitespaceCharacterSet())
return components.joinWithSeparator("")
}
}
Swift 3.0+ (3.0, 3.1, 3.2, 4.0)
extension String {
func removingWhitespaces() -> String {
return components(separatedBy: .whitespaces).joined()
}
}
EDIT
This answer was posted when the question was about removing all whitespaces, the question was edited to only mention leading whitespaces. If you only want to remove leading whitespaces use the following:
extension String {
func removingLeadingSpaces() -> String {
guard let index = firstIndex(where: { !CharacterSet(charactersIn: String($0)).isSubset(of: .whitespaces) }) else {
return self
}
return String(self[index...])
}
}
This String extension removes all whitespace from a string, not just trailing whitespace ...
extension String {
func replace(string:String, replacement:String) -> String {
return self.replacingOccurrences(of: string, with: replacement, options: NSString.CompareOptions.literal, range: nil)
}
func removeWhitespace() -> String {
return self.replace(string: " ", replacement: "")
}
}
Example:
let string = "The quick brown dog jumps over the foxy lady."
let result = string.removeWhitespace() // Thequickbrowndogjumpsoverthefoxylady.
Swift 3
You can simply use this method to remove all normal spaces in a string (doesn't consider all types of whitespace):
let myString = " Hello World ! "
let formattedString = myString.replacingOccurrences(of: " ", with: "")
The result will be:
HelloWorld!
Swift 4, 4.2 and 5
Remove space from front and end only
let str = " Akbar Code "
let trimmedString = str.trimmingCharacters(in: .whitespacesAndNewlines)
Remove spaces from every where in the string
let stringWithSpaces = " The Akbar khan code "
let stringWithoutSpaces = stringWithSpaces.replacingOccurrences(of: " ", with: "")
You can also use regex.
let trimmedString = myString.stringByReplacingOccurrencesOfString("\\s", withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range: nil)
For Swift 3.0+ see the other answers. This is now a legacy answer for Swift 2.x
As answered above, since you are interested in removing the first character the .stringByTrimmingCharactersInSet() instance method will work nicely:
myString.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
You can also make your own character sets to trim the boundaries of your strings by, ex:
myString.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "<>"))
There is also a built in instance method to deal with removing or replacing substrings called stringByReplacingOccurrencesOfString(target: String, replacement: String). It can remove spaces or any other patterns that occur anywhere in your string
You can specify options and ranges, but don't need to:
myString.stringByReplacingOccurrencesOfString(" ", withString: "")
This is an easy way to remove or replace any repeating pattern of characters in your string, and can be chained, although each time through it has to take another pass through your entire string, decreasing efficiency. So you can do this:
myString.stringByReplacingOccurrencesOfString(" ", withString: "").stringByReplacingOccurrencesOfString(",", withString: "")
...but it will take twice as long.
.stringByReplacingOccurrencesOfString() documentation from Apple site
Chaining these String instance methods can sometimes be very convenient for one off conversions, for example if you want to convert a short NSData blob to a hex string without spaces in one line, you can do this with Swift's built in String interpolation and some trimming and replacing:
("\(myNSDataBlob)").stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "<>")).stringByReplacingOccurrencesOfString(" ", withString: "")
For swift 3.0
import Foundation
var str = " Hear me calling"
extension String {
var stringByRemovingWhitespaces: String {
return components(separatedBy: .whitespaces).joined()
}
}
str.stringByRemovingWhitespaces // Hearmecalling
Swift 4
The excellent case to use the regex:
" this is wrong contained teee xt "
.replacingOccurrences(of: "^\\s+|\\s+|\\s+$",
with: "",
options: .regularExpression)
// thisiswrongcontainedteeext
If you are wanting to remove spaces from the front (and back) but not the middle, you should use stringByTrimmingCharactersInSet
let dirtyString = " First Word "
let cleanString = dirtyString.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
If you want to remove spaces from anywhere in the string, then you might want to look at stringByReplacing...
I'd use this extension, to be flexible and mimic how other collections do it:
extension String {
func filter(pred: Character -> Bool) -> String {
var res = String()
for c in self.characters {
if pred(c) {
res.append(c)
}
}
return res
}
}
"this is a String".filter { $0 != Character(" ") } // "thisisaString"
Yet another answer, sometimes the input string can contain more than one space between words. If you need to standardize to have only 1 space between words, try this (Swift 4/5)
let inputString = " a very strange text ! "
let validInput = inputString.components(separatedBy:.whitespacesAndNewlines).filter { $0.count > 0 }.joined(separator: " ")
print(validInput) // "a very strange text !"
Try functional programming to remove white spaces:
extension String {
func whiteSpacesRemoved() -> String {
return self.filter { $0 != Character(" ") }
}
}
Hi this might be late but worth trying. This is from a playground file. You can make it a String extension.
This is written in Swift 5.3
Method 1:
var str = "\n \tHello, playground "
if let regexp = try? NSRegularExpression(pattern: "^\\s+", options: NSRegularExpression.Options.caseInsensitive) {
let mstr = NSMutableString(string: str)
regexp.replaceMatches(in: mstr, options: [], range: NSRange(location: 0, length: str.count), withTemplate: "")
str = mstr as String
}
Result: "Hello, playground "
Method 2:
if let c = (str.first { !($0 == " " || $0 == "\t" || $0 == "\n") }) {
if let nonWhiteSpaceIndex = str.firstIndex(of: c) {
str.replaceSubrange(str.startIndex ..< nonWhiteSpaceIndex, with: "")
}
}
Result: "Hello, playground "
Code less do more.
"Hello World".filter({$0 != " "}) // HelloWorld
You can try This as well
let updatedString = searchedText?.stringByReplacingOccurrencesOfString(" ", withString: "-")
extension String {
var removingWhitespaceAndNewLines: String {
return removing(.whitespacesAndNewlines)
}
func removing(_ forbiddenCharacters: CharacterSet) -> String {
return String(unicodeScalars.filter({ !forbiddenCharacters.contains($0) }))
}
}
If anybody remove extra space from string e.g = "This is the demo text remove extra space between the words."
You can use this Function in Swift 4.
func removeSpace(_ string: String) -> String{
var str: String = String(string[string.startIndex])
for (index,value) in string.enumerated(){
if index > 0{
let indexBefore = string.index(before: String.Index.init(encodedOffset: index))
if value == " " && string[indexBefore] == " "{
}else{
str.append(value)
}
}
}
return str
}
and result will be
"This is the demo text remove extra space between the words."
Swift 3 version
//This function trim only white space:
func trim() -> String
{
return self.trimmingCharacters(in: CharacterSet.whitespaces)
}
//This function trim whitespeaces and new line that you enter:
func trimWhiteSpaceAndNewLine() -> String
{
return self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
}
Trimming white spaces in Swift 4
let strFirstName = txtFirstName.text?.trimmingCharacters(in:
CharacterSet.whitespaces)
For me, the following line used to remove white space.
let result = String(yourString.filter {![" ", "\t", "\n"].contains($0)})
string = string.filter ({!" ".contains($0) })
OK, this is old but I came across this issue myself and none of the answers above worked besides removing all white spaces which can be detrimental to the functionality of your app. My issue was like so:
["This", " is", " my", " array", " it is awesome"]
If trimmed all white spaces this would be the output:
["This", "is", "my", "array", "itisawesome"]
So I needed to eliminate the leading spacing and simply switching from:
let array = jsonData.components(separatedBy: ",")
To
let array = jsonData.components(separatedBy: ", ")
Fixed the issue. Hope someone find this useful in the future.
This worked for me in swift 5
var myString = " Kwame Ch ef "
myString = myString.replacingOccurrences(of: " ", with: "")
print(myString)
output: Kwame Chef
For anyone looking for an answer to remove only the leading whitespaces out of a string (as the question title clearly ask), Here's an answer:
Assuming:
let string = " Hello, World! "
To remove all leading whitespaces, use the following code:
var filtered = ""
var isLeading = true
for character in string {
if character.isWhitespace && isLeading {
continue
} else {
isLeading = false
filtered.append(character)
}
}
print(filtered) // "Hello, World! "
I'm sure there's better code than this, but it does the job for me.
Swift 5+
Remove All whitespace from prefix(start) of the string, you can use similar for sufix/end of the string
extension String {
func deletingPrefix(_ prefix: String) -> String {
guard self.hasPrefix(prefix) else { return self }
return String(self.dropFirst(prefix.count))
}
func removeWhitespacePrefix() -> String {
let prefixString = self.prefix(while: { char in
return char == " "
})
return self.deletingPrefix(String(prefixString))
}
}
Really FAST solution:
usage:
let txt = " hello world "
let txt1 = txt.trimStart() // "hello world "
let txt2 = txt.trimEnd() // " hello world"
usage 2:
let txt = "rr rrr rrhello world r r r r r r"
let txt1 = txt.trimStart(["r", " "]) // "hello world r r r r r r"
let txt2 = txt.trimEnd(["r", " "]) // "rr rrr rrhello world"
if you need to remove ALL whitespaces from string:
txt.replace(of: " ", to: "")
public extension String {
func trimStart(_ char: Character) -> String {
return trimStart([char])
}
func trimStart(_ symbols: [Character] = [" ", "\t", "\r", "\n"]) -> String {
var startIndex = 0
for char in self {
if symbols.contains(char) {
startIndex += 1
}
else {
break
}
}
if startIndex == 0 {
return self
}
return String( self.substring(from: startIndex) )
}
func trimEnd(_ char: Character) -> String {
return trimEnd([char])
}
func trimEnd(_ symbols: [Character] = [" ", "\t", "\r", "\n"]) -> String {
var endIndex = self.count - 1
for i in (0...endIndex).reversed() {
if symbols.contains( self[i] ) {
endIndex -= 1
}
else {
break
}
}
if endIndex == self.count {
return self
}
return String( self.substring(to: endIndex + 1) )
}
}
/////////////////////////
/// ACCESS TO CHAR BY INDEX
////////////////////////
extension StringProtocol {
subscript(offset: Int) -> Character { self[index(startIndex, offsetBy: offset)] }
subscript(range: Range<Int>) -> SubSequence {
let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
return self[startIndex..<index(startIndex, offsetBy: range.count)]
}
subscript(range: ClosedRange<Int>) -> SubSequence {
let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
return self[startIndex..<index(startIndex, offsetBy: range.count)]
}
subscript(range: PartialRangeFrom<Int>) -> SubSequence { self[index(startIndex, offsetBy: range.lowerBound)...] }
subscript(range: PartialRangeThrough<Int>) -> SubSequence { self[...index(startIndex, offsetBy: range.upperBound)] }
subscript(range: PartialRangeUpTo<Int>) -> SubSequence { self[..<index(startIndex, offsetBy: range.upperBound)] }
}
Technically not an answer to the original question but since many posts here give an answer for removing all whitespace, here is an updated, more concise version:
let stringWithouTAnyWhitespace = string.filter {!$0.isWhitespace}
Swift 3 version of BadmintonCat's answer
extension String {
func replace(_ string:String, replacement:String) -> String {
return self.replacingOccurrences(of: string, with: replacement, options: NSString.CompareOptions.literal, range: nil)
}
func removeWhitespace() -> String {
return self.replace(" ", replacement: "")
}
}
To remove all spaces from the string:
let space_removed_string = (yourstring?.components(separatedBy: " ").joined(separator: ""))!
let str = "tHIS is A test"
let swapped_case = "This IS a TEST"
Swift noob here, how to do the second statement programatically?
This function works with all upper/lowercase characters
defined in Unicode, even those from "foreign" languages such as Ä or ć:
func swapCases(_ str : String) -> String {
var result = ""
for c in str.characters { // Swift 1: for c in str {
let s = String(c)
let lo = s.lowercased() //Swift 1 & 2: s.lowercaseString
let up = s.uppercased() //Swift 1 & 2: s.uppercaseString
result += (s == lo) ? up : lo
}
return result
}
Example:
let str = "tHIS is a test ÄöÜ ĂćŒ Α" // The last character is a capital Greek Alpha
let swapped_case = swapCases(str)
print(swapped_case)
// This IS A TEST äÖü ăĆœ α
Use switch statement in-range checks to determine letter case, and use NSString-bridged methods to convert accordingly.
let str = "tHIS is A test"
let swapped_case = "This IS a TEST"
func swapCase(string: String) -> String {
var swappedCaseString: String = ""
for character in string {
switch character {
case "a"..."z":
let uppercaseCharacter = (String(character) as NSString).uppercaseString
swappedCaseString += uppercaseCharacter
case "A"..."Z":
let lowercaseCharacter = (String(character) as NSString).lowercaseString
swappedCaseString += lowercaseCharacter
default:
swappedCaseString += String(character)
}
}
return swappedCaseString
}
swapCase(str)
I'm a bit too late but this works too :-)
let str = "tHIS is A test"
var res = ""
for c in str {
if contains("ABCDEFGHIJKLMNOPQRSTUVWXYZ", c) {
res += "\(c)".lowercaseString
} else {
res += "\(c)".uppercaseString
}
}
res
In Swift 5 I achieved it by creating a function which iterates through each character of the string, and using string methods to change each character I appended each character back into a new variable:
func reverseCase(string: String) -> String {
var newCase = ""
for char in string {
if char.isLowercase {
newCase.append(char.uppercased())
}
else if char.isUppercase {
newCase.append(char.lowercased())
}
else {
newCase.append(char)
}
}
return newCase
}
Then just pass your string through to the function when you call it in a print statement:
print(reverseCase(string: str))
You already have plenty of good succinct answers but here’s an over-elaborate one for fun.
Really this is a job for map – iterate over a collection (in this case String) and do a thing to each element (here, each Character). Except map takes any collection, but only gives you back an array, which you’d have to then turn into a String again.
But here’s a version of map that, given an extensible collection, gives you back that same kind of extensible collection.
(It does have the limitation of needing both collections to contain the same type, but that’s fine for strings. You could make it return a different type, but then you’d have to tell it which type you wanted i.e. map(s, transform) as String which would be annoying)
func map<C: ExtensibleCollectionType>(source: C, transform: (C.Generator.Element) -> C.Generator.Element) -> C {
var result = C()
for elem in source {
result.append(transform(elem))
}
return result
}
Then to write the transform function, first here’s an extension to character similar to the other answers. It does seem quite unsatisfying that you have to convert to a string just to uppercase a character, is there really no good (international characterset-friendly) way to do this?
extension Character {
var uppercaseCharacter: Character {
let s = String(self).uppercaseString
return s[s.startIndex]
}
var lowercaseCharacter: Character {
let s = String(self).lowercaseString
return s[s.startIndex]
}
}
And the function to flip the case. What I wonder is whether this pattern matching is international-friendly. It seems to be – "A"..."Z" ~= "Ä" returns true.
func flipCase(c: Character) -> Character {
switch c {
case "A"..."Z":
return c.lowercaseCharacter
case "a"..."z":
return c.uppercaseCharacter
default:
return c
}
}
Finally:
let s = map("Hello", flipCase)
// s is a String = "hELLO"
I hope this helps. inputString and resultString are the input and output respectively.
let inputString = "Example"
let outputString = inputString.characters.map { (character) -> Character in
let string = String(character)
let lower = string.lowercased()
let upper = string.uppercased()
return (string == lower) ? Character(upper) : Character(lower)
}
let resultString = String(outputString)