जवाबों:
पुराना सवाल है, लेकिन कैसे:
NSString *newString = [[origString componentsSeparatedByCharactersInSet:
[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]
componentsJoinedByString:@""];
यह गैर-अंकों के सेट पर स्रोत स्ट्रिंग का विस्फोट करता है, फिर एक खाली स्ट्रिंग विभाजक का उपयोग करके उन्हें फिर से जोड़ता है। पात्रों के माध्यम से लेने के रूप में कुशल नहीं है, लेकिन कोड में बहुत अधिक कॉम्पैक्ट है।
NSString *pureNumbers = [pureNumbers stringByTrimmingCharactersInSet: [NSCharacterSet decimalDigitCharacterSet] invertedSet]
काम क्यों नहीं हो रहा है?
[NSCharacterSet decimalDigitCharacterSet]
दूसरे के साथ प्रतिस्थापित करेंगे जिसमें केवल संख्याएँ और अक्षर हैं। आप एक बनाने NSMutableCharaterSet
और एक पारित करने के लिए decimalDigitCharacterSet
, uppercaseLetterCharacterSet
और lowercaseLetterCharacterSet
करने के लिए कर सकते हैं formUnionWithCharacterSet:
। ध्यान दें कि letterCharacterSet
इसमें निशान भी शामिल हैं, इसलिए निम्न- और अपरकेस संस्करण का उपयोग करें।
अन्य उत्तरों के अनुसार सुझाव देने के लिए नियमित अभिव्यक्ति पुस्तकालय का उपयोग करने की कोई आवश्यकता नहीं है - आपके द्वारा बुलाया जाने वाला वर्ग NSScanner
। इसका उपयोग इस प्रकार है:
NSString *originalString = @"(123) 123123 abc";
NSMutableString *strippedString = [NSMutableString
stringWithCapacity:originalString.length];
NSScanner *scanner = [NSScanner scannerWithString:originalString];
NSCharacterSet *numbers = [NSCharacterSet
characterSetWithCharactersInString:@"0123456789"];
while ([scanner isAtEnd] == NO) {
NSString *buffer;
if ([scanner scanCharactersFromSet:numbers intoString:&buffer]) {
[strippedString appendString:buffer];
} else {
[scanner setScanLocation:([scanner scanLocation] + 1)];
}
}
NSLog(@"%@", strippedString); // "123123123"
संपादित करें: मैंने कोड अपडेट कर दिया है क्योंकि मूल मेरे सिर के ऊपर से लिखा गया था और मुझे लगा कि यह लोगों को सही दिशा में इंगित करने के लिए पर्याप्त होगा। ऐसा लगता है कि लोग कोड के बाद हैं वे सीधे अपने आवेदन में सीधे कॉपी-पेस्ट कर सकते हैं।
मैं यह भी मानता हूं कि माइकल पेल्ज़-शर्मन का समाधान उपयोग करने से अधिक उपयुक्त है NSScanner
, इसलिए आप उस पर एक नज़र डालना चाहते हैं।
जो पूछा जा रहा है, उसके लिए स्वीकृत उत्तर ओवरकिल है। यह बहुत सरल है:
NSString *pureNumbers = [[phoneNumberString componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]] componentsJoinedByString:@""];
यह बहुत अच्छा है, लेकिन कोड मेरे लिए iPhone 3.0 एसडीके पर काम नहीं करता है।
अगर आप यहां दिखाए गए अनुसार स्ट्रिप्डस्ट्रिंग को परिभाषित करते हैं, तो मुझे कॉल के BAD ACCESS error
बाद इसे प्रिंट करने का प्रयास करने पर मिलता है scanCharactersFromSet:intoString
।
अगर मुझे यह पसंद है:
NSMutableString *strippedString = [NSMutableString stringWithCapacity:10];
मैं एक रिक्त स्ट्रिंग के साथ समाप्त होता हूं, लेकिन कोड क्रैश नहीं होता है।
मुझे इसके बजाय अच्छे पुराने C का सहारा लेना पड़ा:
for (int i=0; i<[phoneNumber length]; i++) {
if (isdigit([phoneNumber characterAtIndex:i])) {
[strippedString appendFormat:@"%c",[phoneNumber characterAtIndex:i]];
}
}
यद्यपि यह काम करने के उत्तर के साथ एक पुराना प्रश्न है, फिर भी मैं अंतर्राष्ट्रीय प्रारूप समर्थन से चूक गया । सिमोनोबो के समाधान के आधार पर, परिवर्तित चरित्र सेट में एक प्लस चिह्न "+" शामिल है। अंतर्राष्ट्रीय फोन नंबर इस संशोधन द्वारा समर्थित हैं।
NSString *condensedPhoneNumber = [[phoneNumber componentsSeparatedByCharactersInSet:
[[NSCharacterSet characterSetWithCharactersInString:@"+0123456789"]
invertedSet]]
componentsJoinedByString:@""];
स्विफ्ट के भाव हैं
var phoneNumber = " +1 (234) 567-1000 "
var allowedCharactersSet = NSMutableCharacterSet.decimalDigitCharacterSet()
allowedCharactersSet.addCharactersInString("+")
var condensedPhoneNumber = phoneNumber.componentsSeparatedByCharactersInSet(allowedCharactersSet.invertedSet).joinWithSeparator("")
जो आम अंतर्राष्ट्रीय फोन नंबर प्रारूप के रूप में +12345671000 की पैदावार देता है।
यहाँ इस का स्विफ्ट संस्करण है।
import UIKit
import Foundation
var phoneNumber = " 1 (888) 555-5551 "
var strippedPhoneNumber = "".join(phoneNumber.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet))
सबसे लोकप्रिय उत्तर का स्विफ्ट संस्करण:
var newString = join("", oldString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet))
संपादित करें: स्विफ्ट 2 के लिए सिंटैक्स
let newString = oldString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
संपादित करें: स्विफ्ट 3 के लिए सिंटैक्स
let newString = oldString.components(separatedBy: CharacterSet.decimalDigits.inverted).joined(separator: "")
उदाहरण के लिए धन्यवाद। यह केवल एक ही चीज़ है स्कैन के अभाव में वृद्धि की स्थिति में मूलस्ट्रिंग में वर्णों में से एक वर्ण संख्या ऑब्जेक्ट के अंदर नहीं पाया जाता है। मैंने इसे ठीक करने के लिए एक और {} स्टेटमेंट जोड़ा है।
NSString *originalString = @"(123) 123123 abc";
NSMutableString *strippedString = [NSMutableString
stringWithCapacity:originalString.length];
NSScanner *scanner = [NSScanner scannerWithString:originalString];
NSCharacterSet *numbers = [NSCharacterSet
characterSetWithCharactersInString:@"0123456789"];
while ([scanner isAtEnd] == NO) {
NSString *buffer;
if ([scanner scanCharactersFromSet:numbers intoString:&buffer]) {
[strippedString appendString:buffer];
}
// --------- Add the following to get out of endless loop
else {
[scanner setScanLocation:([scanner scanLocation] + 1)];
}
// --------- End of addition
}
NSLog(@"%@", strippedString); // "123123123"
यह ध्यान देने योग्य हो सकता है कि स्वीकृत componentsSeparatedByCharactersInSet:
और componentsJoinedByString:
-बेड उत्तर स्मृति-कुशल समाधान नहीं है। यह वर्ण सेट के लिए, एक सरणी के लिए और एक नए स्ट्रिंग के लिए मेमोरी आवंटित करता है। यहां तक कि अगर ये केवल अस्थायी आवंटन हैं, तो बहुत सारे तार प्रसंस्करण इस तरह से स्मृति को जल्दी से भर सकते हैं।
एक स्मृति मैत्री दृष्टिकोण दृष्टिकोण जगह में स्ट्रिंग की एक परस्पर प्रतिलिपि पर काम करना होगा। NSString पर एक श्रेणी में:
-(NSString *)stringWithNonDigitsRemoved {
static NSCharacterSet *decimalDigits;
if (!decimalDigits) {
decimalDigits = [NSCharacterSet decimalDigitCharacterSet];
}
NSMutableString *stringWithNonDigitsRemoved = [self mutableCopy];
for (CFIndex index = 0; index < stringWithNonDigitsRemoved.length; ++index) {
unichar c = [stringWithNonDigitsRemoved characterAtIndex: index];
if (![decimalDigits characterIsMember: c]) {
[stringWithNonDigitsRemoved deleteCharactersInRange: NSMakeRange(index, 1)];
index -= 1;
}
}
return [stringWithNonDigitsRemoved copy];
}
दो दृष्टिकोणों को प्रोफाइल करते हुए यह लगभग 2/3 कम मेमोरी का उपयोग करके दिखाया गया है।
व्यापक समस्याओं के साथ मदद करने के लिए एक श्रेणी के रूप में शीर्ष समाधान बनाया:
इंटरफेस:
@interface NSString (easyReplace)
- (NSString *)stringByReplacingCharactersNotInSet:(NSCharacterSet *)set
with:(NSString *)string;
@end
implemenation:
@implementation NSString (easyReplace)
- (NSString *)stringByReplacingCharactersNotInSet:(NSCharacterSet *)set
with:(NSString *)string
{
NSMutableString *strippedString = [NSMutableString
stringWithCapacity:self.length];
NSScanner *scanner = [NSScanner scannerWithString:self];
while ([scanner isAtEnd] == NO) {
NSString *buffer;
if ([scanner scanCharactersFromSet:set intoString:&buffer]) {
[strippedString appendString:buffer];
} else {
[scanner setScanLocation:([scanner scanLocation] + 1)];
[strippedString appendString:string];
}
}
return [NSString stringWithString:strippedString];
}
@end
उपयोग:
NSString *strippedString =
[originalString stringByReplacingCharactersNotInSet:
[NSCharacterSet setWithCharactersInString:@"01234567890"
with:@""];
तेजी से 4.1
var str = "75003 Paris, France"
var stringWithoutDigit = (str.components(separatedBy:CharacterSet.decimalDigits)).joined(separator: "")
print(stringWithoutDigit)
उम। पहला उत्तर मुझे पूरी तरह से गलत लगता है। NSScanner वास्तव में पार्सिंग के लिए है। रेगेक्स के विपरीत, यह आपके पास एक समय में एक छोटे से स्ट्रिंग स्ट्रिंग को पार्स कर रहा है। आप इसे एक स्ट्रिंग के साथ आरंभीकृत करते हैं, और यह इस बात का सूचकांक बनाए रखता है कि स्ट्रिंग कितनी दूर है; वह सूचकांक हमेशा उसका संदर्भ बिंदु होता है, और आपके द्वारा दिया गया कोई भी आदेश उस बिंदु के सापेक्ष होता है। आप इसे कहते हैं, "ठीक है, मुझे इस सेट में वर्णों का अगला हिस्सा दें" या "मुझे स्ट्रिंग में आपको मिलने वाला पूर्णांक दें", और वे वर्तमान सूचकांक में शुरू करते हैं, और तब तक आगे बढ़ते हैं जब तक कि उन्हें कुछ ऐसा नहीं मिल जाता है मेल खाते हैं। यदि पहले ही वर्ण पहले से मेल नहीं खाता है, तो विधि NO लौटाती है, और अनुक्रमणिका बढ़ती नहीं है।
पहले उदाहरण में कोड दशमलव वर्णों के लिए "(123) 456-7890" स्कैन कर रहा है, जो पहले से ही पहले चरित्र से विफल हो जाता है, इसलिए स्कैनच्रेक्टर्सफ्रॉम से कॉल करने के लिए फ़ॉरसेट: नक्षत्र: पास-इन स्ट्रिप्ड स्ट्रिप्ड को अकेला छोड़ देता है और NO; कोड पूरी तरह से अनदेखा करता है वापसी मूल्य की जाँच करते हुए, छीन लिया गया बिना छेड़े। यहां तक कि अगर पहला वर्ण एक अंक था, तो वह कोड विफल हो जाएगा, क्योंकि यह केवल पहले डैश या पैरेन या जो भी हो, तब तक प्राप्त अंकों को वापस कर देगा।
यदि आप वास्तव में NSScanner का उपयोग करना चाहते हैं, तो आप लूप में कुछ ऐसा डाल सकते हैं, और NO रिटर्न वैल्यू के लिए जाँच करते रह सकते हैं, और यदि आपको ऐसा लगता है कि आप स्कैन लेक्चर को बढ़ा सकते हैं और फिर से स्कैन कर सकते हैं; और आपको isAtEnd और yada yada yada को भी जांचना होगा। संक्षेप में, नौकरी के लिए गलत उपकरण। माइकल का समाधान बेहतर है।
फोन निष्कर्षण की खोज करने वालों के लिए, आप उदाहरण के लिए, NSDataDetector का उपयोग करके किसी फ़ोन से फ़ोन नंबर निकाल सकते हैं:
NSString *userBody = @"This is a text with 30612312232 my phone";
if (userBody != nil) {
NSError *error = NULL;
NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypePhoneNumber error:&error];
NSArray *matches = [detector matchesInString:userBody options:0 range:NSMakeRange(0, [userBody length])];
if (matches != nil) {
for (NSTextCheckingResult *match in matches) {
if ([match resultType] == NSTextCheckingTypePhoneNumber) {
DbgLog(@"Found phone number %@", [match phoneNumber]);
}
}
}
}
`
मैंने इस सामान्य ऑपरेशन को सरल बनाने के लिए NSString पर एक श्रेणी बनाई।
@interface NSString (AllowCharactersInSet)
- (NSString *)stringByAllowingOnlyCharactersInSet:(NSCharacterSet *)characterSet;
@end
@implementation NSString (AllowCharactersInSet)
- (NSString *)stringByAllowingOnlyCharactersInSet:(NSCharacterSet *)characterSet {
NSMutableString *strippedString = [NSMutableString
stringWithCapacity:self.length];
NSScanner *scanner = [NSScanner scannerWithString:self];
while (!scanner.isAtEnd) {
NSString *buffer = nil;
if ([scanner scanCharactersFromSet:characterSet intoString:&buffer]) {
[strippedString appendString:buffer];
} else {
scanner.scanLocation = scanner.scanLocation + 1;
}
}
return strippedString;
}
@end
यदि आप केवल स्ट्रिंग से संख्याओं को पकड़ना चाहते हैं, तो आप निश्चित रूप से उन्हें बाहर निकालने के लिए नियमित अभिव्यक्तियों का उपयोग कर सकते हैं। Objective-C में regex करने के लिए, RegexKit देखें । संपादित करें: जैसा कि @Nathan बताते हैं, NSScanner का उपयोग करना एक स्ट्रिंग से सभी नंबरों को पार्स करने का एक बहुत सरल तरीका है। मुझे उस विकल्प के बारे में पूरी जानकारी नहीं थी, इसलिए उसे सुझाव देने के लिए उसे सहारा दिया। (मैं खुद भी रेगेक्स का उपयोग करना पसंद नहीं करता, इसलिए मैं उन तरीकों को पसंद करता हूं जिनके लिए उन्हें आवश्यकता नहीं है।
यदि आप प्रदर्शन के लिए फ़ोन नंबर प्रारूपित करना चाहते हैं, तो यह NSNumberFormatter पर एक नज़र डालने के लायक है । मेरा सुझाव है कि ऐसा करने के सुझावों के लिए आप इस संबंधित SO प्रश्न को पढ़ें । याद रखें कि फोन नंबर स्थान और / या स्थान के आधार पर अलग-अलग स्वरूपित किए गए हैं।
जॉन वोगेल के उत्तर के आधार पर यह कुछ बुनियादी परीक्षणों के साथ स्विफ्ट स्ट्रिंग विस्तार के रूप में है।
import Foundation
extension String {
func stringByRemovingNonNumericCharacters() -> String {
return self.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
}
}
और कम से कम बुनियादी कार्यक्षमता साबित करने वाले कुछ परीक्षण:
import XCTest
class StringExtensionTests: XCTestCase {
func testStringByRemovingNonNumericCharacters() {
let baseString = "123"
var testString = baseString
var newString = testString.stringByRemovingNonNumericCharacters()
XCTAssertTrue(newString == testString)
testString = "a123b"
newString = testString.stringByRemovingNonNumericCharacters()
XCTAssertTrue(newString == baseString)
testString = "a=1-2_3@b"
newString = testString.stringByRemovingNonNumericCharacters()
XCTAssertTrue(newString == baseString)
testString = "(999) 999-9999"
newString = testString.stringByRemovingNonNumericCharacters()
XCTAssertTrue(newString.characters.count == 10)
XCTAssertTrue(newString == "9999999999")
testString = "abc"
newString = testString.stringByRemovingNonNumericCharacters()
XCTAssertTrue(newString == "")
}
}
यह ओपी के सवाल का जवाब देता है, लेकिन इसे फोन नंबर से संबंधित पात्रों जैसे "; * # +" में छोड़ने के लिए आसानी से संशोधित किया जा सकता है;
NSString *originalPhoneNumber = @"(123) 123-456 abc";
NSCharacterSet *numbers = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet];
NSString *trimmedPhoneNumber = [originalPhoneNumber stringByTrimmingCharactersInSet:numbers];
];
इसे सरल रखें!
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:@"charactersGoHere"]