Bagaimana kita bisa memeriksa apakah sebuah string terdiri dari angka saja. Saya mengambil substring dari string dan ingin memeriksa apakah itu substring numerik atau bukan.
NSString *newString = [myString substringWithRange:NSMakeRange(2,3)];
Jawaban:
Berikut salah satu cara yang tidak bergantung pada ketepatan terbatas dalam mencoba mengurai string sebagai angka:
NSCharacterSet* notDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
if ([newString rangeOfCharacterFromSet:notDigits].location == NSNotFound)
{
// newString consists only of the digits 0 through 9
}
Lihat +[NSCharacterSet decimalDigitCharacterSet]dan -[NSString rangeOfCharacterFromSet:].
[[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet]]
invertedSetmengembalikan kelas yang membungkus set yang dibuatnya bentuk, dan mengembalikan nilai yang berlawanan untuk semua kueri. Tapi saya tidak tahu pasti.
Saya sarankan menggunakan numberFromString:metode dari kelas NSNumberFormatter , seolah-olah nomor tersebut tidak valid, itu akan mengembalikan nil; jika tidak, ini akan mengembalikan Anda NSNumber.
NSNumberFormatter *nf = [[[NSNumberFormatter alloc] init] autorelease];
BOOL isDecimal = [nf numberFromString:newString] != nil;
NOuntuk string Anda. Juga perlu diketahui: mereka juga mengembalikan YESangka yang diisi dengan spasi. Btw, saya baru saja menambahkan beberapa cuplikan kode aktual ke jawaban Anda, harap Anda tidak keberatan.
Validasi dengan ekspresi reguler, berdasarkan pola "^[0-9]+$", dengan metode berikut -validateString:withPattern:.
[self validateString:"12345" withPattern:"^[0-9]+$"];
"^[0-9]+(.{1}[0-9]+)?$"".".
"^[0-9]{4}$".".", dan panjangnya antara 2 ~ 5.
"^[0-9]{2,5}$"."^-?\d+$"Ekspresi reguler dapat diperiksa di situs web online .
Fungsi helper adalah sebagai berikut.
// 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;
}
Uji di taman bermain.
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 }Dan saya mendapat kesalahanPlayground execution aborted: error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
return matchRange.location != NSNotFound;
^-?\d+$, saya memverifikasinya di situs: regex101.com
Anda dapat membuat NSScanner dan cukup memindai string:
NSDecimal decimalValue;
NSScanner *sc = [NSScanner scannerWithString:newString];
[sc scanDecimal:&decimalValue];
BOOL isDecimal = [sc isAtEnd];
Lihat dokumentasi NSScanner untuk metode lainnya yang dapat dipilih.
isAtEnd.
Saya pikir cara termudah untuk memeriksa bahwa setiap karakter dalam string yang diberikan adalah numerik mungkin:
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");
}
Gunakan salah satu metode pabrik NSCharacterSet lainnya jika Anda ingin kontrol penuh atas karakter yang dapat diterima.
Pertanyaan asli ini tentang Objective-C, tetapi juga diposting bertahun-tahun sebelum Swift diumumkan. Jadi, jika Anda datang ke sini dari Google dan mencari solusi yang menggunakan Swift, ini dia:
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.")
}
Solusi Swift 3 jika perlu memverifikasi bahwa string hanya memiliki angka:
CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: myString))
.invertedtindakan yang tidak perlu dan lainnya.
agar jelas, ini berfungsi untuk integer dalam string.
berikut adalah kategori penolong kecil berdasarkan jawaban John di atas:
dalam file .h
@interface NSString (NumberChecking)
+(bool)isNumber:(NSString *)string;
@end
dalam file .m
#import "NSString+NumberChecking.h"
@implementation NSString (NumberChecking)
+(bool)isNumber {
if([self rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location == NSNotFound) {
return YES;
}else {
return NO;
}
}
@end
pemakaian:
#import "NSString+NumberChecking.h"
if([someString isNumber]) {
NSLog(@"is a number");
}else {
NSLog(@"not a number");
}
Solusi Swift 3 bisa seperti:
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)
}
}
}
Jawaban John Calsbeek hampir benar tetapi menghilangkan beberapa kasus tepi Unicode.
Menurut dokumentasi untukdecimalDigitCharacterSet , set itu mencakup semua karakter yang dikategorikan oleh Unicode sebagai Nd. Dengan demikian jawaban mereka akan diterima, antara lain:
१ (U + 0967 DEVANAGARI DIGIT SATU)᠑ (U + 1811 MONGOLIAN DIGIT SATU)𝟙 (U + 1D7D9 MATEMATIKA DOUBLE-STRUCK DIGIT SATU)Meskipun dalam beberapa hal ini benar - setiap karakter di Ndmemang dipetakan ke digit desimal - hampir pasti tidak seperti yang diharapkan penanya. Pada tulisan ini ada 610 poin kode yang dikategorikan sebagaiNd , hanya sepuluh di antaranya adalah karakter yang diharapkan 0(U + 0030) hingga 9(U + 0039).
Untuk memperbaiki masalah, cukup tentukan dengan tepat karakter yang dapat diterima:
NSCharacterSet* notDigits =
[[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet];
if ([newString rangeOfCharacterFromSet:notDigits].location == NSNotFound)
{
// newString consists only of the digits 0 through 9
}
Namun opsi lain:
- (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;
}
}
Contoh penggunaan:
BOOL isValid = [self isValidNumber:@"1234" regex:@"^[0-9]+$"];
Perpanjangan @ John Calsbeek 'jawaban s, dan klarifikasi @ Jeff dan sirkus @gyratory ' s komentar.
+ (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;
}
Berikut ini dapat ditambahkan sebagai metode kategori untuk 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;
}
Menguji apakah sebuah string adalah angka Mungkin Bermanfaat
int i = [@"12.3" rangeOfCharacterFromSet: [ [NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet] ].location;
if (i == NSNotFound) {
//is a number
}
Ekstensi 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
} }
Untuk Swift 3
var onlyDigits: CharacterSet = CharacterSet.decimalDigits.inverted
if testString.rangeOfCharacter(from: onlyDigits) == nil {
// String only consist digits 0-9
}
Jika Anda memiliki digit yang berasal dari bahasa campuran , yang menggunakan (atau tidak) format 0-9 digit, Anda perlu menjalankan regex yang akan mencari angka apa pun, selanjutnya adalah mengubah semua digit menjadi 0- 9 format (jika Anda membutuhkan nilai sebenarnya):
// 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
}
Cara termudah dan paling andal adalah mencoba menggunakan Double, jika hasilnya nil- tidak dapat dibentuk menjadi angka yang sah.
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]
Info lebih lanjut di dokumentasi: https://developer.apple.com/documentation/swift/double/2926277-init
.karakter