Finding new line character in a String in "Swift 3" - ios

In my app I am receiving some incoming data from a web service. In that data some wrong values can also be received like new line characters. I want to find in response string that if it contains a new line character or not.
Before Swift 3 I was able to do it like this
string.rangeOfString("\n")) == nil)
But in Swift 3 this methods is no longer available. However substring method is available which does with the help of Range.
I want to detect if my string contains "\n" how this would be accomplished using this method in Swift 3.

Short answer for Swift 5+
You can use
string.contains { $0.isNewline }
or KeyPath based syntax
string.contains(where: \.isNewline)
to detect if string contains any newline character.
Long answer
Swift 5 introduced couple of new properties on Character. Those simplify such tests and are more robust then simple check for \n.
Now you can use
myCharacter.isNewline
For complete list check Inspecting a Character section in Character docs
Example:
Character("\n").isNewline // true
Character("\r").isNewline // true
Character("a").isNewline // false

If you just want to know if it is there and don't care where it is, string.contains("\n") will return true if it is there and false if not.

You can also use
yourString.rangeOfCharacter(from: CharacterSet.newlines) != nil
which is more elegant as it's not using harcoded newline character string

Swift 3
string.range(of: "\n")
To check:
if string.range(of: "\n") == nil{
}
Or if you simply want to check the string contains \n or not, Then,
if !str.characters.contains("\n") {
}

.characters.contains() should do the trick:
let s1 = "Hi I'm a string\n with a new line"
s1.characters.contains("\n") // => true
let s2 = "I'm not"
s2.characters.contains("\n") // => false

let string:String = "This is a string"
if string.range(of: "\n") == nil {
print ("contains nil")
}
else {
print("contains new line")
}
perferctly working in swift 3.

Related

Checking if a string contains any special characters in swift while allowing all languages

I saw a similar post to this but none of the answers there helped me. I am looking to check if a string does not contain any special characters using swift regular expressions. I want to allow other iPhone keyboard letters though like Chinese, Hindi, Arabic, Korean, etc.. I only do not want to allow special characters like +, &, #, $, % though.
I have tried using:
func usernameTest(testStr:String) -> Bool {
return testStr.range(of: "^[ !\"#$%&'()*+,-./:;<=>?#\\[\\\\\\]^_`{|}~]+", options: .regularExpression) != nil
}
This did not work though. I thought it would check to see if any special characters were used, but when I tested phrases like "Tom###." and "%Will!!" it returned false. I would have expected this to return true since the strings that I passed in contained one or more of the special characters in the range.
Any help would be appreciated as we want our users to be able to create their usernames in any language but we still do not want to allow spaces or special characters.
you can try this way
var charSet = CharacterSet.init(charactersIn: "##$%+_)(")
var string2 = "test#3"
if let strvalue = string2.rangeOfCharacter(from: charSet)
{
print("true")
}
in the characterset init you can give the special characters which you want to check the occurance.
You must remove character "^" in the regex. So your function should look like this:
func usernameTest(testStr:String) -> Bool {
return testStr.range(of: "[ !\"#$%&'()*+,-./:;<=>?#\\[\\\\\\]^_`{|}~]+", options: .regularExpression) != nil }
func usernameTest(testStr:String) -> Bool {
let letters = CharacterSet.punctuationCharacters
let range = testStr.rangeOfCharacter(from: letters)
// range will be nil if no letters is found
if range != nil {
return true
}
else {
return false
}
}
try this one

How to validate a name(John D'Largy) in iOS Swift4.2?

i tried all possibilities in stack-overflow (link1, link2) answers no use for me.
I am using following Regex to validate a first name. In online case (OnlineRegex) it is working fine but when i implemented in mobile it is not working.
Please help me
func isValidName() -> Bool {
let RegEx = "^[a-zA-Z]+(([\\'\\,\\.\\-\\ ][a-zA-Z ])?[a-zA-Z]*)*$"
let Test = NSPredicate(format:"SELF MATCHES %#", RegEx)
return Test.evaluate(with: self)
}
i am calling above function as
let str = "John D'Largy"
if str.isValidName(){
print("Valid")
}else{ print("Not valid")}
Output : "Valid"
Same function i am calling to validate my first text feild i am getting "Not valid"
if firstNameTxt.text.isValidName(){
print("Valid")
}else{ print("Not valid")}
i entered same text in mobile keyword
OutPut: "Not valid"
Did i missing something? or Should i have to change regex value?.
Any suggestions.
Thanks in Advance.
You may use
(?:[a-zA-Z]+(?:['‘’,.\\s-]?[a-zA-Z]+)*)?
The code you have already requires the full string match and you need no explicit anchors like ^ / \A and $ / \z.
Also, since the single quotation marks are automatically converted to curly quotes, you should either add them to the regex or turn off the behavior.
One of the most important things about thi regex is that it should be able to match partially correct string, thus all of the parts are optional (i.e. they can match 0 chars). It is wrapped with an optional non-capturing group ((?:...)?) that matches 1 or 0 occurrences.
Regex details
[a-zA-Z]+ - 1 or more letters
(?: - start of the inner non-capturing group:
['‘’,.\\s-]? - 1 or 0 whitespaces, single quotes, hyphens
[a-zA-Z]+ - 1+ letters
)* - 0 or more repetitions.
Note: to match any Unbicode letter, use \\p{L} instead of [a-zA-Z].
Graph:
See, I tried your code in the playground and changed the syntax a bit but not the logic
Below is the code snippet, try running that in your playground
func isValidName(str: String) -> Bool {
let RegEx = "^[a-zA-Z]+(([\\'\\,\\.\\-\\ ][a-zA-Z ])?[a-zA-Z]*)*$"
let Test = NSPredicate(format:"SELF MATCHES %#", RegEx)
return Test.evaluate(with: str)
}
func check(){
let str = "John D'Largy"
if isValidName(str: str){
print("Valid")
}else{
print("Not valid")
}
}
check()
Hope it helps!

Understanding function with string validation

Consider following:
extension String {
func isValidEmail() -> Bool {
let characterset = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
print(characterset)
if self.rangeOfCharacter(from: characterset.inverted) != nil {
return false
} else {
return true
}
}
}
var name = "Login"
name.isValidEmail() // print true
var incorretLogin = "Loginъ"
incorretLogin.isValidEmail() // print false
Yes, function is work. But im in confussion - how its work?
If i understand correct it work like that:
it take set of characters, then check if all of tested string characters contain symbols from set, and if it is not, then it return false.
Ok, but what is inverted for? If i remove inverted, result will be wrong:
var name = "Login"
name.isValidEmail() // false
var incorretLogin = "Logъin"
incorretLogin.isValidEmail() // false
Now i understand nothing.
If function check simply if string letters are from character set, then why is it matter if set inverted or not?
Could someone explain?
I play a bit in playground:
let characterset = CharacterSet(charactersIn: "a")
print(characterset)
print(characterset.inverted)
Print same result:
<CFCharacterSet Items(U+0061)>
<CFCharacterSet Items(U+0061)>
inverted "returns an inverted copy of the receiver." (see https://developer.apple.com/documentation/foundation/characterset).
In your case inverted means all the characters except the ones you provide in the initializer (all characters except letters and digits). So the method returns false if the email string contains any character that is not a letter or a digit.
Playground example:
According to the documentation
rangeOfCharacter(from:)
Finds and returns the range in the receiver of the first character from a given character set.
The receiver is the string being checked. When no character from the set is found in the string, nil is returned.
When the set is inverted, it contains all invalid characters. Hence, rangeOfCharacter(from:) returns the location of the first invalid character. That is why your first approach works.
When you remove inverted, the call returns the location of the first valid character. Since "Logъin" has both valid and invalid characters, both calls return false. If you call your second function on a string consisting entirely of invalid characters, e.g. "Логин", you would get true.
Note that you can simplify the implementation by removing if:
let characterset = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
return self.rangeOfCharacter(from: characterset.inverted) == nil

Replaced String in Swift 2

So I'm trying to build my app for iOS 9 and am running into one problem. Before, I had a button that would take the string from a label and add it to a string that would take a person to lmgtfy and automatically search for the contents of the string, but now I'm running into an error with map(). Here is the code that worked in iOS 8:
#IBAction func googleButton() {
let replaced = String(map(originalString.generate()) { $0 == " " ? "+" : $0 })
if let url = NSURL(string: "http://google.com/?q=\(replaced)") {
UIApplication.sharedApplication().openURL(url)
}
print(replaced)
}
So now the error I'm getting says, "'map' is unavailable: call the 'map()' method on the sequence." Any ideas? Also, I'm not positive that link will work because it is supposed to be lmgtfy but I couldn't submit this question unless I changed the URL to google.
As of Swift 2, String no longer conforms to SequenceType, therefore you can't call generate on it. Instead you need to use the characters property to obtain a String.CharacterView, which does conform to SequenceType.
Also with Swift 2: map is a method in an extension of SequenceType. Therefore you call it like a method, instead of a free function:
let str = "ab cd ef gh"
let replaced = String(str.characters.map { $0 == " " ? "+" : $0 })
// "ab+cd+ef+gh"
You could also do:
let replaced = str.stringByReplacingOccurrencesOfString(" ", withString: "+")
// "ab+cd+ef+gh"

How to capitalize each word in a string using Swift iOS

Is there a function to capitalize each word in a string or is this a manual process?
For e.g. "bob is tall"
And I would like "Bob Is Tall"
Surely there is something and none of the Swift IOS answers I have found seemed to cover this.
Are you looking for capitalizedString
Discussion
A string with the first character in each word changed to its corresponding uppercase value, and all remaining characters set to their corresponding lowercase values.
and/or capitalizedStringWithLocale(_:)
Returns a capitalized representation of the receiver using the specified locale.
For strings presented to users, pass the current locale ([NSLocale currentLocale]). To use the system locale, pass nil.
Swift 3:
var lowercased = "hello there"
var stringCapitalized = lowercased.capitalized
//prints: "Hello There"
Since iOS 9 a localised capitalization function is available as capitalised letters may differ in languages.
if #available(iOS 9.0, *) {
"istanbul".localizedCapitalizedString
// In Turkish: "İstanbul"
}
An example of the answer provided above.
var sentenceToCap = "this is a sentence."
println(sentenceToCap.capitalizedStringWithLocale(NSLocale.currentLocale()) )
End result is a string "This Is A Sentence"
For Swift 3 it has been changed to capitalized .
Discussion
This property performs the canonical (non-localized) mapping. It is suitable for programming operations that require stable results not depending on the current locale.
A capitalized string is a string with the first character in each word changed to its corresponding uppercase value, and all remaining characters set to their corresponding lowercase values. A “word” is any sequence of characters delimited by spaces, tabs, or line terminators (listed under getLineStart(_:end:contentsEnd:for:)). Some common word delimiting punctuation isn’t considered, so this property may not generally produce the desired results for multiword strings.
Case transformations aren’t guaranteed to be symmetrical or to produce strings of the same lengths as the originals. See lowercased for an example.
There is a built in function for that
nameOfString.capitalizedString
This will capitalize every word of string. To capitalize only the first letter you can use:
nameOfString.replaceRange(nameOfString.startIndex...nameOfString.startIndex, with: String(nameOfString[nameOfString.startIndex]).capitalizedString)
Older Thread
Here is what I came up with that seems to work but I am open to anything that is better.
func firstCharacterUpperCase(sentenceToCap:String) -> String {
//break it into an array by delimiting the sentence using a space
var breakupSentence = sentenceToCap.componentsSeparatedByString(" ")
var newSentence = ""
//Loop the array and concatinate the capitalized word into a variable.
for wordInSentence in breakupSentence {
newSentence = "\(newSentence) \(wordInSentence.capitalizedString)"
}
// send it back up.
return newSentence
}
or if I want to use this as an extension of the string class.
extension String {
var capitalizeEachWord:String {
//break it into an array by delimiting the sentence using a space
var breakupSentence = self.componentsSeparatedByString(" ")
var newSentence = ""
//Loop the array and concatinate the capitalized word into a variable.
for wordInSentence in breakupSentence {
newSentence = "\(newSentence) \(wordInSentence.capitalizedString)"
}
// send it back up.
return newSentence
}
}
Again, anything better is welcome.
Swift 5 version of Christopher Wade's answer
let str = "my string"
let result = str.capitalized(with: NSLocale.current)
print(result) // prints My String

Resources