web-dev-qa-db-ja.com

文字列が数値かどうかを調べる

文字列が数字のみで構成されているかどうかを確認するにはどうすればよいですか。文字列から部分文字列を取り出しており、数値部分文字列かどうかを確認したいです。

NSString *newString = [myString substringWithRange:NSMakeRange(2,3)];
89
Abhinav

以下は、文字列を数値として解析しようとする精度の制限に依存しない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:]

233
John Calsbeek

NSNumberFormatter クラスのnumberFromString:メソッドを使用することをお勧めします。番号が無効である場合は、nilを返します。それ以外の場合、NSNumberが返されます。

NSNumberFormatter *nf = [[[NSNumberFormatter alloc] init] autorelease];
BOOL isDecimal = [nf numberFromString:newString] != nil;
31
Sam

正規表現、パターン_"^[0-9]+$"_、次のメソッド_-validateString:withPattern:_で検証します。

_[self validateString:"12345" withPattern:"^[0-9]+$"];
_
  1. 「123.123」が考慮される場合
    • パターン"^[0-9]+(.{1}[0-9]+)?$"を使用
  2. _"."_。なしの正確に4桁の数字の場合
    • パターン_"^[0-9]{4}$"_を使用。
  3. _"."_のない数字で、長さが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;
}
_

Swift 3バージョン:

遊び場でテストします。

_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)
_
10
AechoLiu

NSScannerを作成して、単純に文字列をスキャンできます。

NSDecimal decimalValue;
NSScanner *sc = [NSScanner scannerWithString:newString];
[sc scanDecimal:&decimalValue];
BOOL isDecimal = [sc isAtEnd];

NSScannerのドキュメント から選択する他の方法を確認してください。

8
Regexident

特定の文字列内のすべての文字が数値であることを確認する最も簡単な方法は、おそらく次のとおりだと思います。

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ファクトリメソッドのいずれかを使用します。

6
Tommy

文字列に数字しか含まれていないことを確認する必要がある場合のSwift 3ソリューション:

CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: myString))
6
plamkata__

この元の質問は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.")
}
5
TwoStraws

明確にするために、これは文字列の整数に対して機能します。

上記のジョンの回答に基づいた小さなヘルパーカテゴリがあります。

.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");
}
4
MrTristan

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)
        }
    }
}
4
hhamm

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
}
2
ravron

さらに別のオプション:

- (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]+$"];
1
LuisCien

混合言語 からの数字がある場合、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
}
0
OhadM

Swiftの場合

var onlyDigits: CharacterSet = CharacterSet.decimalDigits.inverted
if testString.rangeOfCharacter(from: onlyDigits) == nil {
  // String only consist digits 0-9
}
0
Mert Celik

@ 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

0
Ariel

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
}  }
0
Bhavesh Patel

文字列が数字かどうかをテストする

int i = [@"12.3" rangeOfCharacterFromSet: [ [NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet] ].location;

if (i == NSNotFound) {
     //is a number
}
0
Ashok Kumar