NSPredicate search for number in NSString - iphone

I have to find number in NSString using NSPredicate. I am using following code.
NSString *test = #"[0-9]";
NSString *testString = #"ab9";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(%# CONTAINS[c] %#)", test,testString];
BOOL bResult = [predicate evaluateWithObject:testString];
This code is searching for number at only start. I have also tried with #"[0-9]+" and #"[0-9]*" theses expressions but not getting correct result.

Use this
NSCharacterSet *set= [NSCharacterSet alphanumericCharacterSet];
if ([string rangeOfCharacterFromSet:[set invertedSet]].location == NSNotFound) {
// contains A-Z,a-z, 0-9
} else {
// invalid
}
See if it works

When you say
[predicate testString]
You're actually sending 'testString' message (ie: calling 'testString' method) into predicate object. There is no such thing.
I believe what you should be sending instead is 'evaluateWithObject' message, ie:
BOOL bResult = [predicate evaluateWithObject:testString];
The evaluateWithObject method reference says:
Returns a Boolean value that indicates whether a given object matches
the conditions specified by the receiver.

Use NSCharacterSet to analyse NSString.
NSCharacterSet *set= [NSCharacterSet alphanumericCharacterSet];
NSString testString = #"This#9";
BOOL bResult = [testString rangeOfCharacterFromSet:[set invertedSet]].location != NSNotFound;
if(bResult)
NSLog(#"symbol found");
set = [NSCharacterSet uppercaseLetterCharacterSet];
bResult = [password rangeOfCharacterFromSet:set].location != NSNotFound;
if(bResult)
NSLog(#"upper case latter found");
set = [NSCharacterSet lowercaseLetterCharacterSet];
bResult = [password rangeOfCharacterFromSet:set].location != NSNotFound;
if(bResult)
NSLog(#"lower case latter found");
set = [NSCharacterSet decimalDigitCharacterSet];
bResult = [password rangeOfCharacterFromSet:set].location != NSNotFound;
if(bResult)
NSLog(#"digit found");

Related

iPhone Regex for GUIDs

I was searching around finding some easy regex for iPhone to validate if a NSString is in a valid Hex format, containing only characters from 0-9 and a-f. The same for GUID's. Or is there already a function built in to check if a GUID is valid?
I only found some posts about creating GUIDs. This SO answer is creating GUID's in the format I'm using them.
Sample GUID
ADD2B9F7-A699-4EF3-9A70-130B92154B11
To simplify Zaph's correct answer, just add this method to a category on NSString:
-(BOOL) isGuid {
NSString *regexString = #"[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}";
NSRange guidValidationRange = [self rangeOfString:regexString options:NSRegularExpressionSearch];
return (guidValidationRange.location == 0 && guidValidationRange.length == self.length);
}
One way is to use NSCharacterSet:
NSString *testCharacters = #"ABCDEFabcdef0123456789-";
NSCharacterSet *testCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:testCharacters] invertedSet];
NSString *testString1 = #"ADD2B9F7-A699-4EF3-9A70-130B92154B11";
NSRange range1 = [testString1 rangeOfCharacterFromSet:testCharacterSet];
NSLog(#"testString1: %#", (range1.location == NSNotFound) ? #"Good" : #"Bad");
NSString *testString2 = #"zDD2B9F7-A699-4EF3-9A70-130B92154B11";
NSRange range2 = [testString2 rangeOfCharacterFromSet:testCharacterSet];
NSLog(#"testString2: %#", (range2.location == NSNotFound) ? #"Good" : #"Bad");
NSLog output:
testString1: Good
testString2: Bad
or using REs:
NSString *reString = #"[a-fA-F0-9-]+";
NSString *testString1 = #"ADD2B9F7-A699-4EF3-9A70-130B92154B11";
NSRange range1 = [testString1 rangeOfString:reString options:NSRegularExpressionSearch];
NSLog(#"testString1: %#", (range1.location != NSNotFound && range1.length == testString1.length) ? #"Good" : #"Bad");
NSString *testString2 = #"zDD2B9F7-A699-4EF3-9A70-130B92154B11";
NSRange range2 = [testString2 rangeOfString:reString options:NSRegularExpressionSearch];
NSLog(#"testString2: %#", (range1.location != NSNotFound && range2.length == testString2.length) ? #"Good" : #"Bad");
For a more rigorous GUID match:
NSString *reString = #"[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}";

NSString value validation in iOS

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
}
}

NSTextCheckingResult for phone numbers

Can someone tell me why this evaluates every time to true?!
The input is: jkhkjhkj. It doesn't matter what I type into the phone field. It's every time true...
NSRange range = NSMakeRange (0, [phone length]);
NSTextCheckingResult *match = [NSTextCheckingResult phoneNumberCheckingResultWithRange:range phoneNumber:phone];
if ([match resultType] == NSTextCheckingTypePhoneNumber)
{
return YES;
}
else
{
return NO;
}
Here is the value of match:
(NSTextCheckingResult *) $4 = 0x0ab3ba30 <NSPhoneNumberCheckingResult: 0xab3ba30>{0, 8}{jkhkjhkj}
I was using RegEx and NSPredicate but I've read that since iOS4 it's recommended to use NSTextCheckingResult but I can't find any good tutorials or examples on this.
Thanks in advance!
You are using the class incorrectly. NSTextCheckingResult is the result of a text checking that is done by NSDataDetector or NSRegularExpression. Use NSDataDetector instead:
NSError *error = NULL;
NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypePhoneNumber error:&error];
NSRange inputRange = NSMakeRange(0, [phone length]);
NSArray *matches = [detector matchesInString:phone options:0 range:inputRange];
// no match at all
if ([matches count] == 0) {
return NO;
}
// found match but we need to check if it matched the whole string
NSTextCheckingResult *result = (NSTextCheckingResult *)[matches objectAtIndex:0];
if ([result resultType] == NSTextCheckingTypePhoneNumber && result.range.location == inputRange.location && result.range.length == inputRange.length) {
// it matched the whole string
return YES;
}
else {
// it only matched partial string
return NO;
}

How to check if a string contains an URL

i have text message and I want to check whether it is containing text "http" or URL exists in that.
How will I check it?
NSString *string = #"xxx http://someaddress.com";
NSString *substring = #"http:";
Case sensitive example:
NSRange textRange = [string rangeOfString:substring];
if(textRange.location != NSNotFound){
//Does contain the substring
}else{
//Does not contain the substring
}
Case insensitive example:
NSRange textRange = [[string lowercaseString] rangeOfString:[substring lowercaseString]];
if(textRange.location != NSNotFound){
//Does contain the substring
}else{
//Does not contain the substring
}
#Cyprian offers a good option.
You could also consider using a NSRegularExpression which would give you far more flexibility assuming that's what you need, e.g. if you wanted to match http:// and https://.
Url usually has http or https in it
You can use your custom method containsString to check for those strings.
- (BOOL)containsString:(NSString *)string {
return [self containsString:string caseSensitive:NO];
}
- (BOOL)containsString:(NSString*)string caseSensitive:(BOOL)caseSensitive {
BOOL contains = NO;
if (![NSString isNilOrEmpty:self] && ![NSString isNilOrEmpty:string]) {
NSRange range;
if (!caseSensitive) {
range = [self rangeOfString:string options:NSCaseInsensitiveSearch];
} else {
range = [self rangeOfString:string];
}
contains = (range.location != NSNotFound);
}
return contains;
}
Example :
[yourString containsString:#"http"]
[yourString containsString:#"https"]

Checking if a string is a number on iPhone

How can I check if an input string is a number like x.y?
Try this code,
NSString *nameRegex =#"[0-9]+\\.[0-9]$";
NSPredicate *nameTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", nameRegex];
BOOL isDecimalNumber=[nameTest evaluateWithObject:string];
There is one more solution.
NSString *str = #"123456";
NSCharacterSet *decimalSet = [NSCharacterSet decimalDigitCharacterSet];
BOOL valid = [[str stringByTrimmingCharactersInSet: decimalSet] isEqualToString:#""];