文字列が数字のみで構成されているかどうかを確認するにはどうすればよいですか。文字列から部分文字列を取り出しており、数値部分文字列かどうかを確認したいです。
NSString *newString = [myString substringWithRange:NSMakeRange(2,3)];
以下は、文字列を数値として解析しようとする精度の制限に依存しない1つの方法です。
NSCharacterSet* notDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
if ([newString rangeOfCharacterFromSet:notDigits].location == NSNotFound)
{
// newString consists only of the digits 0 through 9
}
見る - +[NSCharacterSet decimalDigitCharacterSet]
および -[NSString rangeOfCharacterFromSet:]
。
NSNumberFormatter クラスのnumberFromString:
メソッドを使用することをお勧めします。番号が無効である場合は、nilを返します。それ以外の場合、NSNumberが返されます。
NSNumberFormatter *nf = [[[NSNumberFormatter alloc] init] autorelease];
BOOL isDecimal = [nf numberFromString:newString] != nil;
正規表現、パターン_"^[0-9]+$"
_、次のメソッド_-validateString:withPattern:
_で検証します。
_[self validateString:"12345" withPattern:"^[0-9]+$"];
_
"^[0-9]+(.{1}[0-9]+)?$"
を使用"."
_。なしの正確に4桁の数字の場合"^[0-9]{4}$"
_を使用。"."
_のない数字で、長さが2〜5の場合。"^[0-9]{2,5}$"
_を使用。正規表現は、 オンラインWebサイト で確認できます。
ヘルパー関数は次のとおりです。
_// 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)
_
NSScannerを作成して、単純に文字列をスキャンできます。
NSDecimal decimalValue;
NSScanner *sc = [NSScanner scannerWithString:newString];
[sc scanDecimal:&decimalValue];
BOOL isDecimal = [sc isAtEnd];
NSScannerのドキュメント から選択する他の方法を確認してください。
特定の文字列内のすべての文字が数値であることを確認する最も簡単な方法は、おそらく次のとおりだと思います。
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ファクトリメソッドのいずれかを使用します。
文字列に数字しか含まれていないことを確認する必要がある場合のSwift 3ソリューション:
CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: myString))
この元の質問はObjective-Cに関するものでしたが、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.")
}
明確にするために、これは文字列の整数に対して機能します。
上記のジョンの回答に基づいた小さなヘルパーカテゴリがあります。
.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の答え はほぼ正しいですが、Unicode Edgeのいくつかのケースを省略しています。
decimalDigitCharacterSet
のドキュメント に従って、そのセットにはUnicodeでNd
として分類されるすべての文字が含まれます。したがって、彼らの答えは、とりわけ受け入れます:
१
(U + 0967 DEVANAGARI DIGIT ONE)᠑
(U + 1811モンゴルディジット1)????
(U + 1D7D9数学的なダブルストラットデジワン)ある意味ではこれは正しいですが、Nd
の各文字は10進数字にマップされますが、それは質問者が期待したものとはほぼ間違いありません。これを書いている時点で Nd
として分類された610個のコードポイント があり、そのうち10個だけが予想される文字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]+$"];
混合言語 からの数字がある場合、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
}
Swiftの場合
var onlyDigits: CharacterSet = CharacterSet.decimalDigits.inverted
if testString.rangeOfCharacter(from: onlyDigits) == nil {
// String only consist digits 0-9
}
@ John Calsbeekの答えの拡張と@Jeffおよび@ gyratory circusのコメント。
+ (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;
}
最も簡単で信頼性の高い方法は、結果が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
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
} }
文字列が数字かどうかをテストする
int i = [@"12.3" rangeOfCharacterFromSet: [ [NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet] ].location;
if (i == NSNotFound) {
//is a number
}