Làm cách nào để xác thực chuỗi nhập vào a UITextField
? Tôi muốn kiểm tra xem chuỗi là số, bao gồm cả dấu thập phân.
Làm cách nào để xác thực chuỗi nhập vào a UITextField
? Tôi muốn kiểm tra xem chuỗi là số, bao gồm cả dấu thập phân.
Câu trả lời:
Tôi sử dụng mã này trong ứng dụng Mac của mình, mã này tương tự hoặc tương tự sẽ hoạt động với iPhone. Nó dựa trên các biểu thức chính quy RegexKitLite và chuyển văn bản sang màu đỏ khi nó không hợp lệ.
static bool TextIsValidValue( NSString* newText, double &value )
{
bool result = false;
if ( [newText isMatchedByRegex:@"^(?:|0|[1-9]\\d*)(?:\\.\\d*)?$"] ) {
result = true;
value = [newText doubleValue];
}
return result;
}
- (IBAction) doTextChanged:(id)sender;
{
double value;
if ( TextIsValidValue( [i_pause stringValue], value ) ) {
[i_pause setTextColor:[NSColor blackColor]];
// do something with the value
} else {
[i_pause setTextColor:[NSColor redColor]];
}
}
(?:|0|[1-9]\\d*)(?:\\.\\d*)
để xem ý nghĩa của nó. Cũng xem Regex Wikipedia
Bạn có thể làm điều đó trong một vài dòng như sau:
BOOL valid;
NSCharacterSet *alphaNums = [NSCharacterSet decimalDigitCharacterSet];
NSCharacterSet *inStringSet = [NSCharacterSet characterSetWithCharactersInString:myInputField.text];
valid = [alphaNums isSupersetOfSet:inStringSet];
if (!valid) // Not numeric
- điều này là để xác thực đầu vào chỉ là ký tự số. Xem tài liệu để NSCharacterSet
biết các tùy chọn khác. Bạn có thể sử dụng characterSetWithCharactersInString để chỉ định bất kỳ bộ ký tự đầu vào hợp lệ nào.
Có một số cách bạn có thể làm điều này:
nil
nếu nó không thể.IMO, sử dụng một cái gì đó tương tự -[NSString doubleValue]
sẽ không phải là lựa chọn tốt nhất vì cả hai @"0.0"
và @"abc"
sẽ có DoubleValue bằng 0. Tất cả các phương thức * value đều trả về 0 nếu chúng không thể chuyển đổi chuỗi đúng cách, vì vậy sẽ khó phân biệt giữa một chuỗi hợp lệ của @"0"
và một chuỗi không hợp lệ. Một cái gì đó giống như của Cstrtol
chức năng sẽ có cùng một vấn đề.
Tôi nghĩ rằng sử dụng NSNumberFormatter sẽ là lựa chọn tốt nhất, vì nó có tính đến ngôn ngữ (tức là số lượng @"1,23"
ở Châu Âu, so với @"1.23"
ở Hoa Kỳ).
NSNumberFormatter * f = [[NSNumberFormatter alloc] init]; NSNumber * n = [f numberFromString:@"34jfkjdskj80"]; NSLog(@"N: %@", n);
NSScanner
, như NSNumberFormatter
, tính đến ngôn ngữ khi phân tích chuỗi, miễn là bạn sử dụng setLocale:
trên đối tượng máy quét (ví dụ: bạn có thể cung cấp [NSLocale currentLocale]
).
Nếu bạn muốn người dùng chỉ được phép nhập các chữ số, bạn có thể làm cho ViewController triển khai một phần của UITextFieldDelegate và xác định phương thức này:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *resultingString = [textField.text stringByReplacingCharactersInRange: range withString: string];
// The user deleting all input is perfectly acceptable.
if ([resultingString length] == 0) {
return true;
}
NSInteger holder;
NSScanner *scan = [NSScanner scannerWithString: resultingString];
return [scan scanInteger: &holder] && [scan isAtEnd];
}
Có lẽ có nhiều cách hiệu quả hơn, nhưng tôi thấy đây là một cách khá tiện lợi . Và phương thức này phải dễ dàng thích ứng để xác thực các giá trị nhân đôi hoặc bất cứ điều gì: chỉ cần sử dụng scanDouble: hoặc tương tự.
#pragma mark - UItextfield Delegate
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if ([string isEqualToString:@"("]||[string isEqualToString:@")"]) {
return TRUE;
}
NSLog(@"Range ==%d ,%d",range.length,range.location);
//NSRange *CURRANGE = [NSString rangeOfString:string];
if (range.location == 0 && range.length == 0) {
if ([string isEqualToString:@"+"]) {
return TRUE;
}
}
return [self isNumeric:string];
}
-(BOOL)isNumeric:(NSString*)inputString{
BOOL isValid = NO;
NSCharacterSet *alphaNumbersSet = [NSCharacterSet decimalDigitCharacterSet];
NSCharacterSet *stringSet = [NSCharacterSet characterSetWithCharactersInString:inputString];
isValid = [alphaNumbersSet isSupersetOfSet:stringSet];
return isValid;
}
Dưới đây là một số dấu gạch đầu dòng kết hợp câu trả lời của Peter Lewis ở trên ( Kiểm tra xem đầu vào cho UITextField chỉ là số ) với NSPredicates
#define REGEX_FOR_NUMBERS @"^([+-]?)(?:|0|[1-9]\\d*)(?:\\.\\d*)?$"
#define REGEX_FOR_INTEGERS @"^([+-]?)(?:|0|[1-9]\\d*)?$"
#define IS_A_NUMBER(string) [[NSPredicate predicateWithFormat:@"SELF MATCHES %@", REGEX_FOR_NUMBERS] evaluateWithObject:string]
#define IS_AN_INTEGER(string) [[NSPredicate predicateWithFormat:@"SELF MATCHES %@", REGEX_FOR_INTEGERS] evaluateWithObject:string]
Đối với kiểm tra số nguyên, nó sẽ là:
- (BOOL) isIntegerNumber: (NSString*)input
{
return [input integerValue] != 0 || [input isEqualToString:@"0"];
}
Bạn có thể sử dụng doubleValue của chuỗi như
NSString *string=@"1.22";
double a=[string doubleValue];
tôi nghĩ rằng điều này sẽ trả về là 0.0 nếu chuỗi không hợp lệ (nó có thể ném ra một ngoại lệ, trong trường hợp đó bạn có thể bắt nó, các tài liệu nói 0.0 tho). thêm thông tin ở đây
Xin chào, có cùng một vấn đề và tôi không thấy câu trả lời mà tôi đã sử dụng được đăng, vì vậy nó ở đây.
Tôi đã tạo và kết nối trường văn bản của mình qua IB. Khi tôi kết nối nó với mã của mình qua Control + Drag, tôi đã chọn Hành động, sau đó chọn sự kiện Chỉnh sửa Đã thay đổi. Điều này kích hoạt phương thức trên mỗi mục nhập ký tự. Bạn có thể sử dụng một sự kiện khác cho phù hợp.
Sau đó, tôi sử dụng mã đơn giản này để thay thế văn bản. Lưu ý rằng tôi đã tạo bộ ký tự của riêng mình để bao gồm ký tự thập phân / dấu chấm và số. Về cơ bản, phân tách chuỗi trên các ký tự không hợp lệ, sau đó nối lại chúng với chuỗi rỗng.
- (IBAction)myTextFieldEditingChangedMethod:(UITextField *)sender {
NSCharacterSet *validCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@".0123456789"];
NSCharacterSet *invalidCharacterSet = validCharacterSet.invertedSet;
sender.text = [[sender.text componentsSeparatedByCharactersInSet:invalidCharacterSet] componentsJoinedByString:@""];
}
Tín dụng: Xóa tất cả trừ số khỏi NSString
Trò chơi muộn nhưng đây là một danh mục nhỏ tiện dụng mà tôi sử dụng đó là các chữ số thập phân và ký hiệu địa phương được sử dụng cho nó. liên kết đến ý chính của nó ở đây
@interface NSString (Extension)
- (BOOL) isAnEmail;
- (BOOL) isNumeric;
@end
@implementation NSString (Extension)
/**
* Determines if the current string is a valid email address.
*
* @return BOOL - True if the string is a valid email address.
*/
- (BOOL) isAnEmail
{
NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
return [emailTest evaluateWithObject:self];
}
/**
* Determines if the current NSString is numeric or not. It also accounts for the localised (Germany for example use "," instead of ".") decimal point and includes these as a valid number.
*
* @return BOOL - True if the string is numeric.
*/
- (BOOL) isNumeric
{
NSString *localDecimalSymbol = [[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator];
NSMutableCharacterSet *decimalCharacterSet = [NSMutableCharacterSet characterSetWithCharactersInString:localDecimalSymbol];
[decimalCharacterSet formUnionWithCharacterSet:[NSCharacterSet alphanumericCharacterSet]];
NSCharacterSet* nonNumbers = [decimalCharacterSet invertedSet];
NSRange r = [self rangeOfCharacterFromSet: nonNumbers];
if (r.location == NSNotFound)
{
// check to see how many times the decimal symbol appears in the string. It should only appear once for the number to be numeric.
int numberOfOccurances = [[self componentsSeparatedByString:localDecimalSymbol] count]-1;
return (numberOfOccurances > 1) ? NO : YES;
}
else return NO;
}
@end
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(string.length > 0)
{
NSCharacterSet *numbersOnly = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
NSCharacterSet *characterSetFromTextField = [NSCharacterSet characterSetWithCharactersInString:string];
BOOL stringIsValid = [numbersOnly isSupersetOfSet:characterSetFromTextField];
return stringIsValid;
}
return YES;
}
IMO, cách tốt nhất để hoàn thành mục tiêu của bạn là hiển thị bàn phím số thay vì bàn phím bình thường. Điều này hạn chế những khóa nào có sẵn cho người dùng. Điều này làm giảm bớt nhu cầu xác thực và quan trọng hơn là nó ngăn người dùng mắc lỗi. Bàn phím số cũng đẹp hơn nhiều để nhập số vì các phím lớn hơn đáng kể.
Trong trình tạo giao diện, chọn UITextField, đi tới Trình kiểm tra thuộc tính và thay đổi "Loại bàn phím" thành "Bảng thập phân".
Điều đó sẽ làm cho bàn phím trông như thế này:
Điều duy nhất cần làm là đảm bảo người dùng không nhập hai chữ số thập phân. Bạn có thể làm điều này trong khi họ đang chỉnh sửa. Thêm mã sau vào bộ điều khiển chế độ xem của bạn. Mã này loại bỏ vị trí thập phân thứ hai ngay khi được nhập. Nó xuất hiện với người dùng như thể số thập phân thứ 2 chưa bao giờ xuất hiện ngay từ đầu.
- (void)viewDidLoad
{
[super viewDidLoad];
[self.textField addTarget:self
action:@selector(textFieldDidChange:)
forControlEvents:UIControlEventEditingChanged];
}
- (void)textFieldDidChange:(UITextField *)textField
{
NSString *text = textField.text;
NSRange range = [text rangeOfString:@"."];
if (range.location != NSNotFound &&
[text hasSuffix:@"."] &&
range.location != (text.length - 1))
{
// There's more than one decimal
textField.text = [text substringToIndex:text.length - 1];
}
}
@property (strong) NSNumberFormatter *numberFormatter;
@property (strong) NSString *oldStringValue;
- (void)awakeFromNib
{
[super awakeFromNib];
self.numberFormatter = [[NSNumberFormatter alloc] init];
self.oldStringValue = self.stringValue;
[self setDelegate:self];
}
- (void)controlTextDidChange:(NSNotification *)obj
{
NSNumber *number = [self.numberFormatter numberFromString:self.stringValue];
if (number) {
self.oldStringValue = self.stringValue;
} else {
self.stringValue = self.oldStringValue;
}
}
Chủ đề cũ, nhưng điều đáng nói là Apple đã giới thiệu NSRegularExpression
trong iOS 4.0. (Lấy biểu thức chính quy từ câu trả lời của Peter)
// Look for 0-n digits from start to finish
NSRegularExpression *noFunnyStuff = [NSRegularExpression regularExpressionWithPattern:@"^(?:|0|[1-9]\\d*)(?:\\.\\d*)?$" options:0 error:nil];
// There should be just one match
if ([noFunnyStuff numberOfMatchesInString:<#theString#> options:0 range:NSMakeRange(0, <#theString#>.length)] == 1)
{
// Yay, digits!
}
Tôi đề nghị lưu trữ NSRegularExpression
phiên bản ở đâu đó.
Tôi muốn một trường văn bản chỉ cho phép số nguyên. Đây là những gì tôi đã kết thúc (sử dụng thông tin từ đây và nơi khác):
Tạo định dạng số nguyên (trong UIApplicationDelegate để nó có thể được sử dụng lại):
@property (nonatomic, retain) NSNumberFormatter *integerNumberFormatter;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Create and configure an NSNumberFormatter for integers
integerNumberFormatter = [[NSNumberFormatter alloc] init];
[integerNumberFormatter setMaximumFractionDigits:0];
return YES;
}
Sử dụng bộ lọc trong UITextFieldDelegate:
@interface MyTableViewController : UITableViewController <UITextFieldDelegate> {
ictAppDelegate *appDelegate;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// Make sure the proposed string is a number
NSNumberFormatter *inf = [appDelegate integerNumberFormatter];
NSString* proposedString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSNumber *proposedNumber = [inf numberFromString:proposedString];
if (proposedNumber) {
// Make sure the proposed number is an integer
NSString *integerString = [inf stringFromNumber:proposedNumber];
if ([integerString isEqualToString:proposedString]) {
// proposed string is an integer
return YES;
}
}
// Warn the user we're rejecting the change
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
return NO;
}
Không quá thanh lịch, nhưng đơn giản :)
- (BOOL) isNumber: (NSString*)input
{
return [input doubleValue] != 0 || [input isEqualToString:@"0"] || [input isEqualToString:@"0.0"];
}
Chấp nhận các giá trị thập phân trong các trường văn bản có một dấu chấm (.) Hoạt động với iPad và iPhone trong Swift 3
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let inverseSet = NSCharacterSet(charactersIn:"0123456789").inverted
let components = string.components(separatedBy: inverseSet)
let filtered = components.joined(separator: "")
if filtered == string {
return true
} else {
if string == "." {
let countdots = textField.text!.components(separatedBy:".").count - 1
if countdots == 0 {
return true
}else{
if countdots > 0 && string == "." {
return false
} else {
return true
}
}
}else{
return false
}
}
}
Để mang tính quốc tế hơn (và không chỉ có màu Hoa Kỳ ;-)), chỉ cần thay thế trong mã trên bằng
-(NSNumber *) getNumber
{
NSString* localeIdentifier = [[NSLocale autoupdatingCurrentLocale] localeIdentifier];
NSLocale *l_en = [[NSLocale alloc] initWithLocaleIdentifier: localeIdentifier] ;
return [self getNumberWithLocale: [l_en autorelease] ];
}
Câu trả lời này sử dụng NSFormatter như đã nói trước đây. Kiểm tra nó ra:
@interface NSString (NSNumber)
- (BOOL) isNumberWithLocale:(NSLocale *) stringLocale;
- (BOOL) isNumber;
- (NSNumber *) getNumber;
- (NSNumber *) getNumberWithLocale:(NSLocale*) stringLocale;
@end
@implementation NSString (NSNumber)
- (BOOL) isNumberWithLocale:(NSLocale *) stringLocale
{
return [self getNumberWithLocale:stringLocale] != nil;
}
- (BOOL) isNumber
{
return [ self getNumber ] != nil;
}
- (NSNumber *) getNumber
{
NSLocale *l_en = [[NSLocale alloc] initWithLocaleIdentifier: @"en_US"] ;
return [self getNumberWithLocale: [l_en autorelease] ];
}
- (NSNumber *) getNumberWithLocale:(NSLocale*) stringLocale
{
NSNumberFormatter *formatter = [[ [ NSNumberFormatter alloc ] init ] autorelease];
[formatter setLocale: stringLocale ];
return [ formatter numberFromString:self ];
}
@end
Tôi hi vọng nó giúp ích cho ai đó. =)
#import "NSString+Extension.h"
//@interface NSString (Extension)
//
//- (BOOL) isAnEmail;
//- (BOOL) isNumeric;
//
//@end
@implementation NSString (Extension)
- (BOOL) isNumeric
{
NSString *emailRegex = @"[0-9]+";
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
return [emailTest evaluateWithObject:self];
// NSString *localDecimalSymbol = [[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator];
// NSMutableCharacterSet *decimalCharacterSet = [NSMutableCharacterSet characterSetWithCharactersInString:localDecimalSymbol];
// [decimalCharacterSet formUnionWithCharacterSet:[NSCharacterSet alphanumericCharacterSet]];
//
// NSCharacterSet* nonNumbers = [decimalCharacterSet invertedSet];
// NSRange r = [self rangeOfCharacterFromSet: nonNumbers];
//
// if (r.location == NSNotFound)
// {
// // check to see how many times the decimal symbol appears in the string. It should only appear once for the number to be numeric.
// int numberOfOccurances = [[self componentsSeparatedByString:localDecimalSymbol] count]-1;
// return (numberOfOccurances > 1) ? NO : YES;
// }
// else return NO;
}
Trong Swift 4:
let formatString = "12345"
if let number = Decimal(string:formatString){
print("String contains only number")
}
else{
print("String doesn't contains only number")
}
Điều này bao gồm: Kiểm soát phần thập phân (bao gồm số lượng số thập phân được phép), kiểm soát sao chép / dán, dấu phân cách quốc tế.
Các bước:
Đảm bảo rằng bộ điều khiển chế độ xem của bạn kế thừa từ UITextFieldDelegate
lớp MyViewController: UIViewController, UITextFieldDelegate {...
Trong viewDidLoad, hãy đặt đại biểu kiểm soát của bạn thành tự:
ghi đè func viewDidLoad () {super.viewDidLoad (); yourTextField.delegate = self}
Triển khai phương pháp sau và cập nhật hằng số "decsAllowed" với số lượng số thập phân mong muốn hoặc 0 nếu bạn muốn một số tự nhiên.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let decsAllowed: Int = 2
let candidateText = NSString(string: textField.text!).replacingCharacters(in: range, with: string)
let decSeparator: String = NumberFormatter().decimalSeparator!;
let splitted = candidateText.components(separatedBy: decSeparator)
let decSeparatorsFound = splitted.count - 1
let decimalPart = decSeparatorsFound > 0 ? splitted.last! : ""
let decimalPartCount = decimalPart.characters.count
let characterSet = NSMutableCharacterSet.decimalDigit()
if decsAllowed > 0 {characterSet.addCharacters(in: decSeparator)}
let valid = characterSet.isSuperset(of: CharacterSet(charactersIn: candidateText)) &&
decSeparatorsFound <= 1 &&
decsAllowed >= decimalPartCount
return valid
}
Nếu sau đó, bạn cần chuyển đổi chuỗi đó thành một số một cách an toàn, bạn chỉ có thể sử dụng kiểu ép kiểu Double (yourstring) hoặc Int (yourstring), hoặc cách học thuật hơn:
let formatter = NumberFormatter()
let theNumber: NSNumber = formatter.number(from: yourTextField.text)!
+ (BOOL) TextIsValidValue:(NSString*)newText:(double)&value:
...