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]]
invertedSet
mengembalikan 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;
NO
untuk string Anda. Juga perlu diketahui: mereka juga mengembalikan YES
angka 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))
.inverted
tindakan 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 Nd
memang 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