เราจะตรวจสอบได้อย่างไรว่าสตริงประกอบด้วยตัวเลขเท่านั้น ฉันกำลังดึงสตริงย่อยออกจากสตริงและต้องการตรวจสอบว่าเป็นสตริงย่อยที่เป็นตัวเลขหรือไม่
NSString *newString = [myString substringWithRange:NSMakeRange(2,3)];
เราจะตรวจสอบได้อย่างไรว่าสตริงประกอบด้วยตัวเลขเท่านั้น ฉันกำลังดึงสตริงย่อยออกจากสตริงและต้องการตรวจสอบว่าเป็นสตริงย่อยที่เป็นตัวเลขหรือไม่
NSString *newString = [myString substringWithRange:NSMakeRange(2,3)];
คำตอบ:
นี่เป็นวิธีหนึ่งที่ไม่ต้องอาศัยความแม่นยำที่ จำกัด ในการพยายามแยกวิเคราะห์สตริงเป็นตัวเลข:
NSCharacterSet* notDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
if ([newString rangeOfCharacterFromSet:notDigits].location == NSNotFound)
{
// newString consists only of the digits 0 through 9
}
ดูและ+[NSCharacterSet decimalDigitCharacterSet]
-[NSString rangeOfCharacterFromSet:]
[[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet]]
invertedSet
กำลังส่งคืนคลาสที่ห่อชุดที่สร้างแบบฟอร์มและส่งคืนค่าตรงกันข้ามสำหรับการสืบค้นทั้งหมด แต่ฉันไม่รู้แน่ชัด
ฉันขอแนะนำให้ใช้numberFromString:
วิธีการจากคลาสNSNumberFormatterราวกับว่าตัวเลขไม่ถูกต้องมันจะคืนค่าศูนย์ มิฉะนั้นจะส่งคืน NSNumber ให้คุณ
NSNumberFormatter *nf = [[[NSNumberFormatter alloc] init] autorelease];
BOOL isDecimal = [nf numberFromString:newString] != nil;
NO
สตริงของคุณ สิ่งที่ควรรู้: พวกเขายังส่งคืนYES
ตัวเลขที่มีช่องว่าง แต่ฉันเพิ่งเพิ่มข้อมูลโค้ดที่แท้จริงลงในคำตอบของคุณหวังว่าคุณจะไม่รังเกียจ
ตรวจสอบโดยการแสดงออกปกติโดยรูปแบบด้วยวิธีการดังต่อไปนี้"^[0-9]+$"
-validateString:withPattern:
[self validateString:"12345" withPattern:"^[0-9]+$"];
"^[0-9]+(.{1}[0-9]+)?$"
"."
หลักโดยไม่ต้อง
"^[0-9]{4}$"
ที่มีรูปแบบ"."
และความยาวอยู่ระหว่าง 2 ~ 5
"^[0-9]{2,5}$"
ที่มีรูปแบบ"^-?\d+$"
คุณสามารถตรวจสอบนิพจน์ทั่วไปได้ในเว็บไซต์ออนไลน์เว็บไซต์ออนไลน์
ฟังก์ชันตัวช่วยมีดังต่อไปนี้
// Validate the input string with the given pattern and
// return the result as a boolean
- (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;
}
ทดสอบในสนามเด็กเล่น
import UIKit
import Foundation
func validate(_ str: String, pattern: String) -> Bool {
if let range = str.range(of: pattern, options: .regularExpression) {
let result = str.substring(with: range)
print(result)
return true
}
return false
}
let a = validate("123", pattern: "^-?[0-9]+")
print(a)
func numberOnly(string: String) -> Int { let expression = "" let regex = NSRegularExpression.init(pattern: expression, options: .caseInsensitive) let numberOfMatches = regex.numberOfMatches(in: string, options: .reportProgress, range: NSRange.init(location: 0, length: string.characters.count)) if numberOfMatches == 0 { return Int(string)! } return 0 }
และฉันได้รับข้อผิดพลาดPlayground execution aborted: error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
return matchRange.location != NSNotFound;
^-?\d+$
ฉันตรวจสอบแล้วบนเว็บไซต์: regex101.com
คุณสามารถสร้าง NSScanner และสแกนสตริง:
NSDecimal decimalValue;
NSScanner *sc = [NSScanner scannerWithString:newString];
[sc scanDecimal:&decimalValue];
BOOL isDecimal = [sc isAtEnd];
ตรวจสอบเอกสารของ NSScannerสำหรับวิธีการเพิ่มเติมให้เลือก
isAtEnd
ลืมสายสุดท้ายที่จะ
ฉันคิดว่าวิธีที่ง่ายที่สุดในการตรวจสอบว่าอักขระทุกตัวในสตริงที่กำหนดเป็นตัวเลขน่าจะเป็น:
NSString *trimmedString = [newString stringByTrimmingCharactersInSet:[NSCharacterSet decimalDigitCharacterSet]];
if([trimmedString length])
{
NSLog(@"some characters outside of the decimal character set found");
}
else
{
NSLog(@"all characters were in the decimal character set");
}
ใช้หนึ่งในวิธีการโรงงาน NSCharacterSet อื่น ๆ หากคุณต้องการควบคุมอักขระที่ยอมรับได้อย่างสมบูรณ์
คำถามเดิมนี้เกี่ยวกับ Objective-C แต่ก็มีการโพสต์เมื่อหลายปีก่อนที่ Swift จะประกาศ ดังนั้นหากคุณมาที่นี่จาก Google และกำลังมองหาโซลูชันที่ใช้ Swift คุณจะไปที่นี่:
let testString = "12345"
let badCharacters = NSCharacterSet.decimalDigitCharacterSet().invertedSet
if testString.rangeOfCharacterFromSet(badCharacters) == nil {
print("Test string was a number")
} else {
print("Test string contained non-digit characters.")
}
โซลูชัน Swift 3 หากจำเป็นต้องตรวจสอบว่าสตริงมีเพียงตัวเลข:
CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: myString))
.inverted
และอื่น ๆ
เพื่อความชัดเจนฟังก์ชันนี้สำหรับจำนวนเต็มในสตริง
นี่เป็นหมวดหมู่ผู้ช่วยเล็ก ๆ น้อย ๆ ตามคำตอบของ John ด้านบน:
ในไฟล์. h
@interface NSString (NumberChecking)
+(bool)isNumber:(NSString *)string;
@end
ในไฟล์. m
#import "NSString+NumberChecking.h"
@implementation NSString (NumberChecking)
+(bool)isNumber {
if([self rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location == NSNotFound) {
return YES;
}else {
return NO;
}
}
@end
การใช้งาน:
#import "NSString+NumberChecking.h"
if([someString isNumber]) {
NSLog(@"is a number");
}else {
NSLog(@"not a number");
}
โซลูชัน Swift 3 อาจเป็นดังนี้:
extension String {
var doubleValue:Double? {
return NumberFormatter().number(from:self)?.doubleValue
}
var integerValue:Int? {
return NumberFormatter().number(from:self)?.intValue
}
var isNumber:Bool {
get {
let badCharacters = NSCharacterSet.decimalDigits.inverted
return (self.rangeOfCharacter(from: badCharacters) == nil)
}
}
}
เป็นส่วนหนึ่งของ @John Calsbeek 's คำตอบและการชี้แจงของ@ Jeffและคณะละครสัตว์ @gyratory ' s ความคิดเห็น
+ (BOOL)doesContainDigitsOnly:(NSString *)string
{
NSCharacterSet *nonDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
BOOL containsDigitsOnly = [string rangeOfCharacterFromSet:nonDigits].location == NSNotFound;
return containsDigitsOnly;
}
+ (BOOL)doesContainNonDigitsOnly:(NSString *)string
{
NSCharacterSet *digits = [NSCharacterSet decimalDigitCharacterSet];
BOOL containsNonDigitsOnly = [string rangeOfCharacterFromSet:digits].location == NSNotFound;
return containsNonDigitsOnly;
}
ต่อไปนี้สามารถเพิ่มเป็นวิธีการประเภทสำหรับ NSString
- (BOOL)doesContainDigitsOnly
{
NSCharacterSet *nonDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
BOOL containsDigitsOnly = [self rangeOfCharacterFromSet:nonDigits].location == NSNotFound;
return containsDigitsOnly;
}
- (BOOL)doesContainNonDigitsOnly
{
NSCharacterSet *digits = [NSCharacterSet decimalDigitCharacterSet];
BOOL containsNonDigitsOnly = [self rangeOfCharacterFromSet:digits].location == NSNotFound;
return containsNonDigitsOnly;
}
คำตอบของ John Calsbeekนั้นเกือบจะถูกต้อง แต่ละเว้นกรณีขอบ Unicode บางส่วน
ตามเอกสารdecimalDigitCharacterSet
ชุดที่มีตัวอักษรทั้งหมดแบ่งตาม Unicode Nd
เป็น ดังนั้นคำตอบของพวกเขาจะยอมรับในหมู่คนอื่น ๆ :
१
(ยู + 0967 เดวานาการีดิจิทัล)᠑
(U + 1811 MONGOLIAN DIGIT ONE)𝟙
(U + 1D7D9 คณิตศาสตร์สองชั้นหลักหนึ่ง)ในขณะที่ในแง่หนึ่งสิ่งนี้ถูกต้อง - อักขระแต่ละตัวในNd
จะจับคู่กับเลขฐานสิบ - เกือบจะไม่ใช่สิ่งที่ผู้ถามคาดหวัง จากการเขียนนี้มีจุดรหัส 610 จุดที่แบ่งออกเป็นNd
เพียงสิบตัวเท่านั้นที่เป็นอักขระที่คาดหวัง0
(U + 0030) ถึง9
(U + 0039)
ในการแก้ไขปัญหาเพียงระบุอักขระที่ยอมรับได้:
NSCharacterSet* notDigits =
[[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet];
if ([newString rangeOfCharacterFromSet:notDigits].location == NSNotFound)
{
// newString consists only of the digits 0 through 9
}
อีกทางเลือกหนึ่ง:
- (BOOL)isValidNumber:(NSString*)text regex:(NSString*)regex {
@try {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
return [predicate evaluateWithObject:text];
}
@catch (NSException *exception) {
assert(false);
return NO;
}
}
ตัวอย่างการใช้งาน:
BOOL isValid = [self isValidNumber:@"1234" regex:@"^[0-9]+$"];
ทดสอบว่าสตริงเป็นตัวเลขหรือไม่อาจเป็นประโยชน์
int i = [@"12.3" rangeOfCharacterFromSet: [ [NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet] ].location;
if (i == NSNotFound) {
//is a number
}
ส่วนขยาย Swift:
extension NSString {
func isNumString() -> Bool {
let numbers = NSCharacterSet(charactersInString: "0123456789.").invertedSet
let range = self.rangeOfCharacterFromSet(numbers).location
if range == NSNotFound {
return true
}
return false
} }
สำหรับ Swift 3
var onlyDigits: CharacterSet = CharacterSet.decimalDigits.inverted
if testString.rangeOfCharacter(from: onlyDigits) == nil {
// String only consist digits 0-9
}
เมื่อคุณมีตัวเลขที่มาจากภาษาผสมที่ใช้ (หรือไม่มี) รูปแบบ 0-9 หลักคุณจะต้องเรียกใช้นิพจน์ทั่วไปที่จะค้นหาตัวเลขใด ๆ สิ่งต่อไปคือการแปลงตัวเลขทั้งหมดให้เป็น 0- 9 รูปแบบ (หากคุณต้องการค่าจริง):
// Will look for any language digits
let regex = try NSRegularExpression(pattern: "[^[:digit:]]", options: .caseInsensitive)
let digitsString = regex.stringByReplacingMatches(in: string,
options: NSRegularExpression.MatchingOptions(rawValue: 0),
range: NSMakeRange(0, string.count), withTemplate: "")
// Converting the digits to be 0-9 format
let numberFormatter = NumberFormatter()
numberFormatter.locale = Locale(identifier: "EN")
let finalValue = numberFormatter.number(from: digitsString)
if let finalValue = finalValue {
let actualValue = finalValue.doubleValue
}
วิธีที่ง่ายที่สุดและน่าเชื่อถือที่สุดคือการพยายามร่ายราวกับDouble
ว่าผลลัพธ์คือnil
มันไม่สามารถสร้างเป็นตัวเลขที่ถูกต้องได้
let strings = ["test", "123", "123.2", "-123", "123-3", "123..22", ".02"]
let validNumbers = strings.compactMap(Double.init)
print(validNumbers)
// prints [123.0, 123.2, -123.0, 0.02]
ข้อมูลเพิ่มเติมในเอกสาร: https://developer.apple.com/documentation/swift/double/2926277-init
Simple เขียนนามสกุลสตริง:
extension String {
var isNumeric: Bool {
return self.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
}
}
.
อักขระ