Regular expression for US phone number not working - iphone

This type of questions are asked so many times on SO but i am having problem with expression and its not working for me.
I need to allow only numbers,(,),- in phone number and for that i have code as follows.
But only uncommented expression is working and that is for only numbers no (,),- are allowed and i searched and got other expressions which should allow (,),- but those are not working too.
What could be wrong?
Example: 9876545678, (123) 123-7657
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if ([string isEqualToString:#""]) {
return TRUE;
}
if(textField == aTfdPhone)
{
if ([string isEqualToString:#"."]) {
return NO;
}
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSString *expression = #"^([0-9]+)?(\\.([0-9])?)?$";
// NSString *expression = #"^[(]?[2-9][0-9]{2}[)]?[ -]?[0-9]{3}[ -]?[0-9]{4}$";
// NSString * const expression = #"^([+-]{1})([0-9]{3})$";
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression
options:NSRegularExpressionCaseInsensitive
error:&error];
if (error) {
NSLog(#"error %#", error);
}
NSUInteger numberOfMatches = [regex numberOfMatchesInString:newString
options:0
range:NSMakeRange(0, [newString length])];
if (numberOfMatches == 0){
return NO;
}
}
return TRUE;
}

Your second attempt fails to recognize (123) 123-7657 because of the first digit:
It should be
NSString *expression = #"^[(]?[1-9][0-9]{2}[)]?[ -]?[0-9]{3}[ -]?[0-9]{4}$";
not
NSString *expression = #"^[(]?[2-9][0-9]{2}[)]?[ -]?[0-9]{3}[ -]?[0-9]{4}$";
The only difference is the operator matching the first digit [2-9] would not match 1.

Related

Local search in NSMutalbleArray

I want to search in NSMutalbleArray, my code is :
arrCelebs=[[NSMutableArray alloc] initWithObjects:#"Test 1",#"Test 2",#"Test 42",#"Test 5", nil];
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *arrString1 = txtSearch.text;
NSRange tmprange;
for(NSString *string in arrCelebs) {
tmprange = [arrString1 rangeOfString:string];
if (tmprange.location != NSNotFound) {
NSLog(#"String found");
break;
}
}
return YES;
}
if i enter "t" then it search all the data and i want to add it another array. for display in tableview.
You can use the power of NSPredicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF BEGINSWITH[c] %#", textField.text];
NSArray *filteredArray = [arrCelebs filteredArrayUsingPredicate:predicate];
By using predicate you Can easily get the result efficiently.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", txtSearch.text];
NSArray *ResultArray = [yourArray filteredArrayUsingPredicate:predicate];
return YES;
}
Try :
arr_NewArray = [[NSMutableArray alloc] init];
for (int i = 0; i < [arr_YourArrayToSearch count]; i++)
{
NSString *curString = [string lowercaseString];
NSString *curStringInArray = [[arr_YourArrayToSearch objectAtIndex:i]lowercaseString];
if (![curString rangeOfString:curStringSmall].location == NSNotFound)
{
[arr_NewArray addObject:[arr_YourArrayToSearch objectAtIndex:i]];
}
}
arr_NewArray will give you the array with data matched to your search string.
arrCelebs=[[NSMutableArray alloc] initWithObjects:#"Test 1",#"Test 2",#"Test 42",#"Test 5", nil];
_resultArray = [[NSMutableArray alloc] init];
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *arrString1 = txtSearch.text;
NSRange tmprange;
_resultArray = [[NSMutableArray alloc] init];
for(NSString *string in arrCelebs) {
tmprange = [arrString1 rangeOfString:string];
if (tmprange.location != NSNotFound) {
[_resultArray addObject:string];
}
}
return YES;
}
IF YOU work With UITableView then you cal also put this type of Logic.
Take Two NSMutableArray and add one array to another array in ViewDidLoad method such like,
self.listOfTemArray = [[NSMutableArray alloc] init]; // array no - 1
self.ItemOfMainArray = [[NSMutableArray alloc] initWithObjects:#"YorArrayList", nil]; // array no - 2
[self.listOfTemArray addObjectsFromArray:self.ItemOfMainArray]; // add 2array to 1 array
And Write following delegate Method of UISearchBar
- (BOOL) textFieldDidChange:(UITextField *)textField
{
NSString *name = #"";
NSString *firstLetter = #"";
if (self.listOfTemArray.count > 0)
[self.listOfTemArray removeAllObjects];
if ([searchText length] > 0)
{
for (int i = 0; i < [self.ItemOfMainArray count] ; i = i+1)
{
name = [self.ItemOfMainArray objectAtIndex:i];
if (name.length >= searchText.length)
{
firstLetter = [name substringWithRange:NSMakeRange(0, [searchText length])];
//NSLog(#"%#",firstLetter);
if( [firstLetter caseInsensitiveCompare:searchText] == NSOrderedSame )
{
// strings are equal except for possibly case
[self.listOfTemArray addObject: [self.ItemOfMainArray objectAtIndex:i]];
NSLog(#"=========> %#",self.listOfTemArray);
}
}
}
}
else
{
[self.listOfTemArray addObjectsFromArray:self.ItemOfMainArray ];
}
[self.tblView reloadData];
}
}
Output Show in your Consol.
This exact what you want...
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSMutableArray *resultAry = [[NSMutableArray alloc] init];
for(NSString *string in arrCelebs)
{
NSRange range = [string rangeOfString:textField.text options:NSCaseInsensitiveSearch];
if(range.location != NSNotFound)
{
[resultAry addObject:string];
}
}
yourTableAry=[resultAry mutableCopy];
[yourTable reloadData];
return YES;
}

Parse html NSString with REGEX [duplicate]

This question already has answers here:
Convert first number in an NSString into an Integer?
(6 answers)
Objective-C: Find numbers in string
(7 answers)
Closed 10 years ago.
I have NSString with couple strings like this that the 465544664646 is change between them :
data-context-item-title="465544664646"
How i parse the 465544664646 string to a Array ?
Edit
NSRegularExpression* myRegex = [[NSRegularExpression alloc] initWithPattern:#"(?i)(data-context-item-title=\")(.+?)(\")" options:0 error:nil];
[myRegex enumerateMatchesInString:responseString options:0 range:NSMakeRange(0, [responseString length]) usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop) {
NSRange range = [match rangeAtIndex:1];
NSString *string =[responseString substringWithRange:range];
NSLog(string);
}];
Try this one:
NSString *yourString=#"data-context-item-title=\"465544664646\" data-context-item-title=\"1212121212\"";
NSMutableArray *substrings = [NSMutableArray new];
NSScanner *scanner = [NSScanner scannerWithString:yourString];
[scanner scanUpToString:#"\"" intoString:nil];
while(![scanner isAtEnd]) {
NSString *tempString;
[scanner scanString:#"\"" intoString:nil];
if([scanner scanUpToString:#" " intoString:&tempString]) {
[substrings addObject:tempString];
}
[scanner scanUpToString:#"\"" intoString:nil];
}
//NSLog(#"->%#",substrings); //substrings contains all numbers as string.
for (NSString *str in substrings) {
NSLog(#"->%ld",[str integerValue]); //converted each number to integer value, if you want to store as NSNumber now you can store each of them in array
}
Something like this?
-(NSString *)stringFromOriginalString:(NSString *)origin betweenStartString: (NSString*)start andEndString:(NSString*)end {
NSRange startRange = [origin rangeOfString:start];
if (startRange.location != NSNotFound) {
NSRange targetRange;
targetRange.location = startRange.location + startRange.length;
targetRange.length = [origin length] - targetRange.location;
NSRange endRange = [origin rangeOfString:end options:0 range:targetRange];
if (endRange.location != NSNotFound) {
targetRange.length = endRange.location - targetRange.location;
return [origin substringWithRange:targetRange];
}
}
return nil;
}
You can use
- (NSArray *)componentsSeparatedByString:(NSString *)separator
method like
NSArray *components = [#"data-context-item-title="465544664646" componentsSeparatedByString:#"\""];
Now you should got the string at 2. index
[components objectAtIndex:1]
Now you can create array from that string using the method here
NSString to NSArray

how to validate textfield that allows only single decimal point in textfield?

I need to restrict user to enter only two digit after decimal point. I have achieved this by following code in textfield delegate shouldChangeCharactersInRange. But its allowing to enter more than one dot. how to restrict this? Thanks in advance.
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSArray *sep = [newString componentsSeparatedByString:#"."];
if([sep count]>=2)
{
NSString *sepStr=[NSString stringWithFormat:#"%#",[sep objectAtIndex:1]];
NSLog(#"sepStr:%#",sepStr);
return !([sepStr length]>2);
}
return YES;
The best way is to use Regular Expression in shouldChangeCharactersInRange: delegate method like this
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSString *newStr = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSString *expression = #"^([0-9]*)(\\.([0-9]+)?)?$";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression
options:NSRegularExpressionCaseInsensitive
error:nil];
NSUInteger noOfMatches = [regex numberOfMatchesInString:newStr
options:0
range:NSMakeRange(0, [newStr length])];
if (noOfMatches==0){
return NO;
}
return YES;
}
After implementing this valid strings are:
12.004546
4546.5456465
.5464
0.454
So on....
You can also restrict number of integer after decimal by using this Regular Expression#"^([0-9]*)(\\.([0-9]{0,2})?)?$"
After implementing this valid strings are:
12.00
4546.54
.54
0.45
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSString *sepStr;
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSArray *sep = [newString componentsSeparatedByString:#"."];
if([sep count]>=2)
{
sepStr=[NSString stringWithFormat:#"%#",[sep objectAtIndex:1]];
NSLog(#"sepStr:%#",sepStr);
if([sepStr length] >2)
{
return NO;
}
else
{
return YES;
}
}
return YES;
}
When a dot is entered, you should check whether a dot is present already, and return NO if it is present.
NSString * newString = [textField.text stringByReplacingCharactersInRange: range withString: string];
NSArray * sep = [newString componentsSeparatedByString: #"."];
if([string isEqualToString:#"."] && [sep count] > 1){
//already a . is there.. so don't allow new one
return NO;
}
if ([sep count] >= 2) {
NSString * sepStr = [NSString stringWithFormat: #"%#", [sep objectAtIndex: 1]];
NSLog(#"sepStr:%#", sepStr);
return !([sepStr length] > 2);
}
return YES;
Updated answer for Swift 3 using the reg ex "^([0-9]*)(\\.([0-9]+)?)?$":
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let newText = ((textField.text ?? "") as NSString).replacingCharacters(in: range, with: string)
let expression = "^([0-9]*)(\\.([0-9]+)?)?$"
guard let regex = try? NSRegularExpression(pattern: expression, options: .caseInsensitive) else {
return false
}
let noOfMatches = regex.numberOfMatches(in: newText, options: [], range: NSMakeRange(0, newText.characters.count))
return noOfMatches > 0
}
You can use this method:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSRange temprange = [textField.text rangeOfString:#"."];
if ((temprange.location != NSNotFound) && [string isEqualToString:#"."])
{
return NO;
}
return YES;
}
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSArray *sep = [newString componentsSeparatedByString:#"."];
if([string isEqualToString:#"."]){
if([textField.text containsString:#"."]){
return NO;
}
}
if([sep count] >= 2)
{
NSString *sepStr=[NSString stringWithFormat:#"%#",[sep objectAtIndex:1]];
return !([sepStr length]>2);
}
return YES;
}

UIKeyboardTypeDecimalPad detect if it has comma "," or dot "."

How can I check if the UIKeyboardTypeDecimalPad has a dot/comma? I need this to check how many dots/commas are entered so I can limit them to only 1. I know how to do this when I know that the UIKeyboardTypeDecimalPad has the comma.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSCharacterSet *cs;
NSString *filtered;
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if ([textField.text rangeOfString:#","].location == NSNotFound) {
cs = [[NSCharacterSet characterSetWithCharactersInString:NUMBERSPERIOD] invertedSet];
filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:#""];
return [string isEqualToString:filtered];
}
else {
cs = [[NSCharacterSet characterSetWithCharactersInString:NUMBERS] invertedSet];
filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:#""];
NSUInteger count = 0, length = [newString length];
NSRange range = NSMakeRange(0, length);
while(range.location != NSNotFound)
{
range = [newString rangeOfString: #"," options:0 range:range];
if(range.location != NSNotFound)
{
range = NSMakeRange(range.location + range.length, length - (range.location + range.length));
count++;
}
}
if (count < 2) {
NSArray *sep = [newString componentsSeparatedByString:#","];
if([sep count]>=2)
{
NSString *sepStr=[NSString stringWithFormat:#"%#",[sep objectAtIndex:1]];
return !([sepStr length]>2);
}
return YES;
}
return NO;
}
}
Is there easy way to check if the keyboard has the "," or "."?
I suspect the character on that key is governed by the current locale. I say I suspect because I have not tested this. If this is correct the following should allow you to determine whether a comma or period/decimal point is there:
NSString *symbol = [[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator];

-JSONValue Failed error trace is:Garbage after JSON

I am using Json Parsing with autosuggestion
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
autoCompleteTable.hidden = NO;
NSString *substring = [NSString stringWithString:textField.text];
substring = [substring stringByReplacingCharactersInRange:range withString:string];
if(substring.length>=3)
{
[self getDescriptionData];
[self searchAutocompleteEntriesWithSubstring:substring];
}
else {
[placesArray removeAllObjects];
[autoCompleteTable reloadData];
}
return YES;
}
JSON value is retrieved in getDescription method. but when it is called second tine i am getting error:
-JSONValue failed. Error trace is: (
"Error Domain=org.brautaset.JSON.ErrorDomain Code=10 \"Garbage after JSON\" UserInfo=0x4b60160 {NSLocalizedDescription=Garbage after JSON}"
)
i met the same thing.
After googling and stackflowing, i found nothing.
so i decide to use JSONKit instead:
(github: https://github.com/johnezang/JSONKit)
// sbjson
// NSString *jsonStr = [NSString stringWithCString:[receivedData bytes]
// encoding:NSUTF8StringEncoding];
// NSArray *returnArr = [jsonStr JSONValue];
// jsonkit
JSONDecoder *decoder = [JSONDecoder decoder];
NSError *error;
NSArray *returnArr = [decoder objectWithData:receivedData error:&error];
Finally, this works.