I want to make a regular expression in which user can only enter alphabets.
I am using this piece of code to validate the UITextField.
I am validating the code in shouldChangeCharactersInRange method.
NSString *regex = #"[a-zA-Z]";
NSPredicate *testRegex = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", regex];
if(![testRegex evaluateWithObject:string])
return NO;
It is working fine but I can not delete using BacKspace button As my RegEx doesn't allow this.
How can I make a regular expression which supports alphabets and allow deletion.
Try this out:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)iRange replacementString:(NSString *)iText {
NSString *newString = [iTextView.text stringByReplacingCharactersInRange:iRange withString:iText];
NSString *abnRegex = #"[A-Za-z]+";
NSPredicate *abnTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", abnRegex];
return ([abnTest evaluateWithObject:newString] || newString.length == 0);
}
Can you try with this (Just a work around) :
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (range.length > 0)
{
// We're deleting
return YES;
}
else
{
// We're adding
NSString *regex = #"[a-zA-Z]";
NSPredicate *testRegex = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", regex];
if(![testRegex evaluateWithObject:string])
return NO;
else
return YES;
}
Related
I want to implement some validation in my project, validation is that: Don't allow number 0-9 and A-Z in UITextField, only allow GUJARATI letter in UITextField. I have tried some validation but It was not working. I need some help from anyone.
I have tried this below code:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
//limit the size :
if([self checkValidation:textField] == true)
{
return NO;
}
return YES;
}
- (BOOL)checkValidation:(UITextField *)textField
{
NSString *rejex = [NSString stringWithFormat:#"%#",#"[A-Za-z0-9]"];
NSPredicate *gujTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", rejex];
//if rejex fullfil than it will return true else false.
return [gujTest evaluateWithObject:textField.text];
}
TIA
In your checkValidation function, you are taking textField as an argument and extracting its text property - but you call it in shouldChangeCharactersInRange, and by that point the text property still holds the old value of text, before the update (it gets updated after you return true from this function). Do instead
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
//limit the size :
if([self checkValidation:string] == true)
{
return NO;
}
return YES;
}
- (BOOL)checkValidation:(NSString *)string
{
let stringWithGujaratiCharacters = "અ" // string with all Gujarati letters
let characterSet = CharacterSet(charactersIn: stringWithGujaratiCharacters).inverted // character set containing every character besides Gujarati letters
return string.rangeOfCharacter(from: characterSet) != nil // returns true if string contains characters other than Gujarati letters
}
If you just don't want to allow latin alphanumeric characters, change your characterSet
let characterSet = CharacterSet.alphanumerics
Change textfield to string on below code. it will work.
if([self checkValidation:string] == true)
and
- (BOOL)checkValidation:(NSString *)textField
{
NSString *rejex = [NSString stringWithFormat:#"%#",#"[A-Za-z0-9]"];
NSPredicate *gujTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", rejex];
//if rejex fullfil than it will return true else false.
return [gujTest evaluateWithObject:textField];
}
For this problem it would be better to use a CharacterSet detection. Regular expression don't work very well with unicode. Also, it is better to check for characters your want to allow than the other way around:
let text = textField.text ?? ""
// https://unicode.org/charts/PDF/U0A80.pdf 0x0A80 ... 0x0AFF
let gurajatiCharacterSet = CharacterSet(charactersIn: Unicode.Scalar(0x0A80 as Int)! ... Unicode.Scalar(0x0AFF as Int)!)
return text.rangeOfCharacter(from: gurajatiCharacterSet.inverted) == nil
Objective-C:
NSUInteger minValue = 0x0A80;
NSUInteger maxValue = 0x0AFF;
NSCharacterSet *gurajatiCharacterSet = [NSCharacterSet characterSetWithRange:NSMakeRange(minValue, maxValue - minValue + 1)];
return [textField.text rangeOfCharacterFromSet:[gurajatiCharacterSet invertedSet]].location == NSNotFound;
For this problem you can use NSCharacterSet.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:#"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"];
for (int i = 0; i < [string length]; i++)
{
unichar c = [string characterAtIndex:i];
if (![myCharSet characterIsMember:c])
{
return NO;
}
}
return YES;
}
After a text field is returned I want to check if the text provided is valid. Valid means only letters or a single apostrophe, for names.
I'm pretty new to regular expressions. Is there a simple regular expression I can use for this check, or can someone point me towards some reading material where I can learn to compose a regular expression that will fit my needs?
You can do it like this, but you need to show an error in case the input is invalid.
- (BOOL)textFieldShouldEndEditing:(UITextField *)aTextField
{
NSString *const regularExpression = #"^[a-zA-Z']+$";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regularExpression
options:kNilOptions
error:&error];
if (error) {
// Handle error
}
NSUInteger numberOfMatches = [regex numberOfMatchesInString:aString
options:0
range:NSMakeRange(0, [aString length])];
return numberOfMatches > 0;
}
The regx should be
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
you can use
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if (textField == emailid) {
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:#"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'"] invertedSet];
NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:#""];
;
return [string isEqualToString:filtered];
}
}
You can use the function that checks whether the input should be inserted or not and restrict the characters there. Since your restriction is fairly simple there is no need of regular expressions and you can use characters sets.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSMutableCharacterSet *allowedCharacters = [NSMutableCharacterSet alphanumericCharacterSet];
[allowedCharacters addCharactersInString:#"'"];
if([string rangeOfCharacterFromSet:allowedCharacters.invertedSet].location == NSNotFound){
return YES;
}
return NO;
}
I have to format input string as phone number.For i am using
(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSUInteger newLength = [textField.text length] + [string length] - range.length;
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:NUMBERS_ONLY] invertedSet];
NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:#""];
if (string.length==3||string.length==7) {
filtered =[filtered stringByAppendingString:#"-"];
}
return (([string isEqualToString:filtered])&&(newLength <= CHARACTER_LIMIT));
}
here
#define NUMBERS_ONLY #"1234567890-"
#define CHARACTER_LIMIT 12
but its not editing back.
Please give some ideas
The method you're using is a UITextFieldDelegate method that determines whether or not to allow a change to the text field - given the range and replacement text, should the change be made (YES or NO).
You're trying to format a string while it is being typed - for this you'll also need to update the value of the textField.text property. This could be done in the same method while returning a "NO" afterwards.
For validation,
- (BOOL) isValidPhoneNumber
{
NSString *numberRegex = #"(([+]{1}|[0]{2}){0,1}+[0]{1}){0,1}+[ ]{0,1}+(?:[-( ]{0,1}[0-9]{3}[-) ]{0,1}){0,1}+[ ]{0,1}+[0-9]{2,3}+[0-9- ]{4,8}";
NSPredicate *numberTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#",numberRegex];
return [numberTest evaluateWithObject:self.inputString];
}
You can use this for formatting the string,
self.inputString = #"1234567890"
NSArray *stringComponents = [NSArray arrayWithObjects:[self.inputString substringWithRange:NSMakeRange(0, 3)],
[self.inputString substringWithRange:NSMakeRange(3, 3)],
[self.inputString substringWithRange:NSMakeRange(6, [self.inputString length]-6)], nil];
NSString *formattedString = [NSString stringWithFormat:#"%#-%#-%#", [stringComponents objectAtIndex:0], [stringComponents objectAtIndex:1], [stringComponents objectAtIndex:2]];
I have a TextField in xCode and someone ask me to admit just certain types of characters giving me this text string:
^([A-ZÑÑÁÉÍÓÚÀÈÌÒÙÄËÏÖÜ ])*$
or this one:
^([0-9])*$
I Know a method using UITextFieldDelegate named textField shouldChangeCharactersInRange and this is the way I implement this method:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *allowedCharacters = #"abcdefghijklmnñopqrstuvwxyzABCDEFGHIJKLMÑNOPQRSTUVWXYZ0123456789.#-_ ";
NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:allowedCharacters];
if ([string stringByTrimmingCharactersInSet:characterSet].length == 0)textField.text = [textField.text stringByReplacingCharactersInRange:range withString:string];
return NO;
return YES;
}
if you see, on my programming my variable allowedCharacters stores all my valid characters but is in a different format (I have to write all the allowed characters),
I want to program something similar but with my partner's text format ^([0-9])*$ (text using ranges) how do I do that
Thanks in advance
you can use this:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// Valida el patron que se introduce en el campo de texto
if (![self validateString:string withPattern:#"^([A-Z0-9.#-_ ])*$"]) return NO;
return YES;
}
in the withPattern parameter insert your regex expression, and then here it is the method which does all the magic:
- (BOOL)validateString:(NSString *)string withPattern:(NSString *)pattern
{
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error];
NSAssert(regex, #"Unable to create regular expression");
NSRange textRange = NSMakeRange(0, string.length);
NSRange matchRange = [regex rangeOfFirstMatchInString:string options:NSMatchingReportProgress range:textRange];
BOOL didValidate = NO;
// Did we find a matching range
if (matchRange.location != NSNotFound) didValidate = YES;
return didValidate;
}
test it and tell us how did it go
How to validate a phone number (NSString *) by NSPredicate?
Rules:
minimum 10 digits
maximum 10 digits
the first digit must be 7,8 or 9
Thanks
An NSPredicate based on a regular expression will fit your requirements.
NSString *stringToBeTested = #"8123456789";
NSString *mobileNumberPattern = #"[789][0-9]{9}";
NSPredicate *mobileNumberPred = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", mobileNumberPattern];
BOOL matched = [mobileNumberPred evaluateWithObject:stringToBeTested];
You don't need to keep the pattern in a string by itself, but regexes are complicated enough already so it makes the overall code clearer if you keep it out of the NSPredicate format string.
You can just use below code
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; // return NO to not change text
{
if(textField.tag == 111)
{
if([self MobileNumberValidate:string] == TRUE)
return YES;
else
return NO;
}
return YES;
}
#pragma mark - Mobile Number validation
- (BOOL)MobileNumberValidate:(NSString*)number
{
NSString *numberRegEx = #"[0-9]";
NSPredicate *numberTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", numberRegEx];
if ([numberTest evaluateWithObject:number] == YES)
return TRUE;
else
return FALSE;
}
NSString *phoneNumber = #"1234567890";
NSString *phoneRegex = #"[789][0-9]{3}([0-9]{6})?";
NSPredicate *test = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", phoneRegex];
BOOL matches = [test evaluateWithObject:phoneNumber];
Below code will work for your requirement:
Function:
-(BOOL)validatePhone:(NSString *)enteredPhoneNumber
{
NSString *phoneRegex = #"[789][0-9]{9}";
// OR below for advanced type
//NSString *phoneRegex = #"^((\\+)|(00))[0-9]{6,14}$";
NSPredicate *phoneTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", phoneRegex];
return [phoneTest evaluateWithObject:enteredPhoneNumber];
}
Call it:
if ([self validatePhone:#"9833112299"])
{
NSLog(#"Valid Phone Number");
}
else
{
NSLog(#"Invalid Phone Number");
}
Make it Global using 'extension' use it wherever required
In any one of your view controller class at the end after last } paste below code
extension String
{
func validateMobile() -> Bool
{
return NSPredicate(format: "SELF MATCHES %#","[789][0-9].{9}").evaluate(with: self)
}
}
when you want to validate yourTxtField in any ViewController class simply call as below:
if (yourTxtField.text?.validateMobile())!
{
print("It is 10 digit, starting with 7/8/9")
}
else
{
print("Invalid mobile number")
}