NSString value validation in iOS - iphone

This simple validation method for NSString makes trouble.
I have an NSString value and I want to validate the string, i.e, if the string contains only 'a to z' (or) 'A to Z' (or) '1 to 9' (or) '#,!,&' then the string is valid. If the string contains any other values then this the NSString is invalid, how can i validate this..?
As example:
Valid:
NSString *str="aHrt#2"; // something like this
Invalid:
NSString *str="..gS$"; // Like this

Try using character sets:
NSMutableCharacterSet *set = [NSMutableCharacterSet characterSetWithCharactersInString:#"#!&"];
[set formUnionWithCharacterSet:[NSCharacterSet alphanumericCharacterSet]];
if ([string rangeOfCharacterFromSet:[set invertedSet]].location == NSNotFound) {
// contains a-z, A-Z, 0-9 and &#! only - valid
} else {
// invalid
}

I would do something using stringByTrimmingCharactersInSet
Create an NSCharacterSet containing all valid characters, then trim those characters from the test string, if the string is now empty it is valid, if there are any characters left over, it is invalid
NSCharacterSet *validCharacters = [NSCharacterSet characterSetWithCharactersInString:#"myvalidchars"];
NSString *trimmedString = [testString stringByTrimmingCharactersInSet:validCharachters];
BOOL valid = [trimmedString length] == 0;
Edit:
If you want to control the characters that can be entered into a text field, use textField:shouldChangeCharactersInRange:replacementString: in UITextFieldDelegate
here the testString variable becomes the proposed string and you return YES if there are no invalid characters

The NSPredicate class is what you want
More info about predicate programming. Basically you want "self matches" (your regular expression). After that you can use the evaluateWithObject: method.
EDIT Easier way: (nevermind, as I am editing it wattson posted what I was going to)

You can use the class NSRegularExpression to do this.
https://developer.apple.com/library/mac/documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html

You can also use NSRegularExpression to search your NSString, if it contains only the valid characters (or vice versa).
More info:
Search through NSString using Regular Expression
Use regular expression to find/replace substring in NSString

- (BOOL)validation:(NSString *)string
{
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:#"1234567890abcdefghik"] invertedSet];
NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:#""];
return ([string isEqualToString:filtered]);
}
In your button action:
-(IBAction)ButtonPress{
if ([self validation:activity.text]) {
NSLog(#"Macth here");
}
else {
NSLog(#"Not Match here");
}
}
Replace this "1234567890abcdefghik" with your letters with which you want to match

+(BOOL) validateString: (NSString *) string
{
NSString *regex = #"[A-Z0-9a-z#!&]";
NSPredicate *test = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", emailRegex];
BOOL isValid = [test evaluateWithObject:string];
return isValid;
}

You can simply do it using NSMutableCharacterSet
NSMutableCharacterSet *charactersToKeep = [NSMutableCharacterSet alphanumericCharacterSet];
[charactersToKeep addCharactersInString:#"#?!"];
NSCharacterSet *charactersToRemove = [charactersToKeep invertedSet]
NSString *trimmed = [ str componentsSeparatedByCharactersInSet:charactersToRemove];
if([trimmed length] != 0)
{
//invalid string
}
Reference NSCharacterSet

You can use regex. If every thing fails use brute force like
unichar c[yourString.length];
NSRange raneg={0,2};
[yourString getCharacters:c range:raneg];
// now in for loop
for(int i=0;i<yourString.length;i++)
{
if((c[i]>='A'&&c[i]<='Z')&&(c[i]=='#'||c[i]=='!'||c[i]=='&'))
{
//not the best or most efficient way but will work till you write your regex:P
}
}

Related

How can i find NSString having atlease one charater in iPhone app?

Am working on Message based iPhone app. I have to pass numbers to Webservice if the k like a-z and A-Z i have alert the user to omit the letters from the numbers. How can i find NSString value having a-z and A-Z letters in it? Anyone please help me. Thanks in advance.
That should be it :)
NSCharacterSet *alphaSet = [NSCharacterSet letterCharacterSet];
BOOL valid = [[yourString stringByTrimmingCharactersInSet:alphaSet] isEqualToString:#""];
It removes all the letters from your string, if there is anything left, then valid is NO.
Hope that helps ! :)
Do this:
NSCharacterSet *alphabetSet = [[NSCharacterSet characterSetWithCharactersInString:#"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ"] invertedSet];
if ([yourString rangeOfCharacterFromSet:alphabetSet].location == NSNotFound) {
if(yourString.length >= 1)
{
// has aleast one character
}
}
If you just want to check if there is ANY character in your string use something like this:
if ([yourString length] > 0) {
// nice feature here is, this will also work when yourString is nil! :D
}
---
If you want to do a more complex check you will have to use Regular Expressions. Use NSRegularExpression class like this:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"^[A-Za-z]+$" options:0] error:NULL];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:yourString
options:0
range:NSMakeRange(0, [string length])];
if (numberOfMatches > 0) {
// yourString does only consist of multiple letters
}
^[a-zA-Z]+$ matches only strings that consist of one or more letters only (^ and $ mark the begin and end of a string respectively). ^[0-9]+$ matches numbers only.
NSString * regexName = #"[a-zA-Z] * ";
NSString *testString = #"your string";
NSPredicate *predicate;
predicate = [NSPredicate predicateWithFormat:#"SELF MATCHES %#",regexName];
if ([predicate evaluateWithObject:testString]) {
NSLog(#"true");
}
else{NSLog"string contains numbers or special characters" ;}
From What I understand you want phone Numbers to be entered
First of all you can set the keypad as UIKeyboardTypePhonePad or UIKeyboardTypeNumberPad for the UITextView you are adding the numbers to.
OR
Pass the text to this function
-(BOOL) checkForPhoneNumber:(NSString *) string
{
NSPredicate *confidenceTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#",NUMBER_REGEX];
return [confidenceTest evaluateWithObject:string]?YES:NO;
}
where
#define NUMBER_REGEX #"^[0-9]10?$"

Objective-C: Find consonants in string

I have a string that contains words with consonants and vowels. How can I extract only consonants from the string?
NSString *str = #"consonants.";
Result must be:
cnsnnts
You could make a character set with all the vowels (#"aeiouy")
+ (id)characterSetWithCharactersInString:(NSString *)aString
then use the
- (NSString *)stringByTrimmingCharactersInSet:(NSCharacterSet *)set
method.
EDIT: This will only remove vowels at the beginning and end of the string as pointed out in the other post, what you could do instead is use
- (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator
then stick the components back together. You may also need to include capitalized versions of the vowels in the set, and if you want to also deal with accents (à á è è ê ì etc...) you'll probably have to include that also.
Unfortunately stringByTrimmingCharactersInSet wont work as it only trim leading and ending characters, but you could try using a regular expression and substitution like this:
[[NSRegularExpression
regularExpressionWithPattern:#"[^bcdefghjklmnpqrstvwx]"
options:NSRegularExpressionCaseInsensitive
error:NULL]
stringByReplacingMatchesInString:str
options:0
range:NSMakeRange(0, [str length])
withTemplate:#""]
You probably want to tune the regex and options for your needs.
Possible, for sure not-optimal, solution. I'm printing intermediate results for your learning. Take care of memory allocation (I didn't care). Hopefully someone will send you a better solution, but you can copy and paste this for the moment.
NSString *test = #"Try to get all consonants";
NSMutableString *found = [[NSMutableString alloc] init];
NSInteger loc = 0;
NSCharacterSet *consonants = [NSCharacterSet characterSetWithCharactersInString:#"bcdfghjklmnpqrstvwxyz"];
while(loc!=NSNotFound && loc<[test length]) {
NSRange r = [[test lowercaseString] rangeOfCharacterFromSet:consonants options:0 range:NSMakeRange(loc, [test length]-loc)];
if(r.location!=NSNotFound) {
NSString *temp = [test substringWithRange:r];
NSLog(#"Range: %# Temp: %#",NSStringFromRange(r), temp);
[found appendString:temp];
loc=r.location+r.length;
} else {
loc=NSNotFound;
}
}
NSLog(#"Found: %#",found);
Here is a NSString category that does the job:
- (NSString *)consonants
{
NSString *result = [NSString stringWithString:self];
NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:#"aeiou"];
while(1)
{
NSRange range = [result rangeOfCharacterFromSet:characterSet options:NSCaseInsensitiveSearch];
if(range.location == NSNotFound)
break;
result = [result stringByReplacingCharactersInRange:range withString:#""];
}
return result;
}

NSString search whole text for another string

I would like to search for an NSString in another NSString, such that the result is found even if the second one does not start with the first one, for example:
eg: I have a search string "st". I look in the following records to see if any of the below contains this search string, all of them should return a good result, because all of them have "st".
Restaurant
stable
Kirsten
At the moment I am doing the following:
NSComparisonResult result = [selectedString compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
This works only for "stable" in the above example, because it starts with "st" and fails for the other 2. How can I modify this search so that it returns ok for all the 3?
Thanks!!!
Why not google first?
String contains string in objective-c
NSString *string = #"hello bla bla";
if ([string rangeOfString:#"bla"].location == NSNotFound) {
NSLog(#"string does not contain bla");
} else {
NSLog(#"string contains bla!");
}
Compare is used for testing less than/equal/greater than. You should instead use -rangeOfString: or one of its sibling methods like -rangeOfString:options:range:locale:.
I know this is an old thread thought it might help someone.
The - rangeOfString:options:range: method will allow for case insensitive searches on a string and replace letters like ‘ö’ to ‘o’ in your search.
NSString *string = #"Hello Bla Bla";
NSString *searchText = #"bla";
NSUInteger searchOptions = NSCaseInsensitiveSearch | NSDiacriticInsensitiveSearch;
NSRange searchRange = NSMakeRange(0, string.length);
NSRange foundRange = [string rangeOfString:searchText options:searchOptions range:searchRange];
if (foundRange.length > 0) {
NSLog(#"Text Found.");
}
For more comparison options NSString Class Reference
Documentation on the method - rangeOfString:options:range: can be found on the NSString Class Reference

How do I make sure that a string only contains the a–z and A–Z characters?

I'm entering the name of the user where I need to enter only a-z and A-Z only. I want to validate the name please help me.
Thanks in advance
NSCharacterSet *nonAlphabetChars = [[NSCharacterSet characterSetWithCharactersInString:#"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"] invertedSet];
if ([myString rangeOfCharacterFromSet:nonAlphabetChars].location == NSNotFound) {
// myString is valid
...
} else {
// myString contains at least one invalid character
...
}
You could do something like this:
NSCharacterSet *allowed = [NSCharacterSet alphanumericCharacterSet];
NSCharacterSet *forbidden = [allowed invertedSet];
NSRange range = [string rangeOfCharacterFromSet:forbidden];
BOOL isValid = (range.location == NSNotFound);
The alphanumericCharacterSet might not be exactly what you want, see NSCharacterSet for more options.

Replace multiple characters in a string in Objective-C?

In PHP I can do this:
$new = str_replace(array('/', ':', '.'), '', $new);
...to replace all instances of the characters / : . with a blank string (to remove them)
Can I do this easily in Objective-C? Or do I have to roll my own?
Currently I am doing multiple calls to stringByReplacingOccurrencesOfString:
strNew = [strNew stringByReplacingOccurrencesOfString:#"/" withString:#""];
strNew = [strNew stringByReplacingOccurrencesOfString:#":" withString:#""];
strNew = [strNew stringByReplacingOccurrencesOfString:#"." withString:#""];
Thanks,
matt
A somewhat inefficient way of doing this:
NSString *s = #"foo/bar:baz.foo";
NSCharacterSet *doNotWant = [NSCharacterSet characterSetWithCharactersInString:#"/:."];
s = [[s componentsSeparatedByCharactersInSet: doNotWant] componentsJoinedByString: #""];
NSLog(#"%#", s); // => foobarbazfoo
Look at NSScanner and -[NSString rangeOfCharacterFromSet: ...] if you want to do this a bit more efficiently.
There are situations where your method is good enough I think matt.. BTW, I think it's better to use
[strNew setString: [strNew stringByReplacingOccurrencesOfString:#":" withString:#""]];
rather than
strNew = [strNew stringByReplacingOccurrencesOfString:#"/" withString:#""];
as I think you're overwriting an NSMutableString pointer with an NSString which might cause a memory leak.
Had to do this recently and wanted to share an efficient method:
(assuming someText is a NSString or text attribute)
NSString* someText = #"1232342jfahadfskdasfkjvas12!";
(this example will strip numbers from a string)
[someText stringByReplacingOccurrencesOfString:#"[^0-9]" withString:#"" options:NSRegularExpressionSearch range:NSMakeRange(0, [someText length])];
Keep in mind that you will need to escape regex literal characters using Obj-c escape character:
(obj-c uses a double backslash to escape special regex literals)
...stringByReplacingOccurrencesOfString:#"[\\\!\\.:\\/]"
What makes this interesting is that NSRegularExpressionSearch option is little used but can lead to some very powerful controls:
You can find a nice iOS regex tutorial here and more on regular expressions at regex101.com
Essentially the same thing as Nicholas posted above, but if you want to remove everything EXCEPT a set of characters (say you want to remove everything that isn't in the set "ABCabc123") then you can do the following:
NSString *s = #"A567B$%C^.123456abcdefg";
NSCharacterSet *doNotWant = [[NSCharacterSet characterSetWithCharactersInString:#"ABCabc123"] invertedSet];
s = [[s componentsSeparatedByCharactersInSet: doNotWant] componentsJoinedByString: #""];
NSLog(#"%#", s); // => ABC123abc
Useful in stripping out symbols and such, if you only want alphanumeric.
+ (NSString*) decodeHtmlUnicodeCharactersToString:(NSString*)str
{
NSMutableString* string = [[NSMutableString alloc] initWithString:str]; // #&39; replace with '
NSString* unicodeStr = nil;
NSString* replaceStr = nil;
int counter = -1;
for(int i = 0; i < [string length]; ++i)
{
unichar char1 = [string characterAtIndex:i];
for (int k = i + 1; k < [string length] - 1; ++k)
{
unichar char2 = [string characterAtIndex:k];
if (char1 == '&' && char2 == '#' )
{
++counter;
unicodeStr = [string substringWithRange:NSMakeRange(i + 2 , 2)]; // read integer value i.e, 39
replaceStr = [string substringWithRange:NSMakeRange (i, 5)]; // #&39;
[string replaceCharactersInRange: [string rangeOfString:replaceStr] withString:[NSString stringWithFormat:#"%c",[unicodeStr intValue]]];
break;
}
}
}
[string autorelease];
if (counter > 1)
return [self decodeHtmlUnicodeCharactersToString:string];
else
return string;
}
Here is an example in Swift 3 using the regularExpression option of replacingOccurances.
Use replacingOccurrences along with a the String.CompareOptions.regularExpression option.
Example (Swift 3):
var x = "<Hello, [play^ground+]>"
let y = x.replacingOccurrences(of: "[\\[\\]^+<>]", with: "7", options: .regularExpression, range: nil)
print(y)
Output:
7Hello, 7play7ground777
If the characters you wish to remove were to be adjacent to each other you could use the
stringByReplacingCharactersInRange:(NSRange) withString:(NSString *)
Other than that, I think just using the same function several times isn't that bad. It is much more readable than creating a big method to do the same in a more generic way.
Create an extension on String...
extension String {
func replacingOccurrences(of strings:[String], with replacement:String) -> String {
var newString = self
for string in strings {
newString = newString.replacingOccurrences(of: string, with: replacement)
}
return newString
}
}
Call it like this:
aString = aString.replacingOccurrences(of:['/', ':', '.'], with:"")