NSCharacterSet 判断字符串是否为空,你不知道的方法
Lui41V
8年前
<h2>1.判断字符串是否为空,多简单的事,然而你知道 NSCharacterSet 的妙用吗?</h2> <h3>判断字符串是否为空(包括nil,@"",全是空格)的代码:</h3> <pre> <code class="language-objectivec">-(BOOL)IsEmpty:(NSString *)string{ NSCharacterSet *set = [NSCharacterSet whitespaceAndNewlineCharacterSet]; NSString *trimedString = [string stringByTrimmingCharactersInSet:set]; if (trimedString.length != 0 ) { return YES; } return NO; } 简单吧;</code></pre> <h2>提起NSCharacterSet,那就看一下他是个什么东西吧;</h2> <p>NSCharacterSet ,以及它的可变版本 NSMutableCharacterSet ,用面向对象的方式来表示一组Unicode字符。它经常与 NSString 及 NSScanner 组合起来使用,在不同的字符上做过滤、删除或者分割操作。为了给你提供这些字符是哪些字符的直观印象,请看看NSCharacterSet 提供的类方法:</p> <pre> <code class="language-objectivec">alphanumericCharacterSet capitalizedLetterCharacterSet controlCharacterSet decimalDigitCharacterSet decomposableCharacterSet illegalCharacterSet letterCharacterSet lowercaseLetterCharacterSet newlineCharacterSet nonBaseCharacterSet punctuationCharacterSet symbolCharacterSet uppercaseLetterCharacterSet whitespaceAndNewlineCharacterSet whitespaceCharacterSet</code></pre> <p>与它的名字所表述的相反,NSCharacterSet 跟 NSSet 一点关系都没有。</p> <p>虽然底层实现不太一样,但是 NSCharacterSet 在概念上跟 NSIndexSet 还有点相似的。NSIndexSet,之前提到过,表示一个有序的不重复的无符号整数的集合。Unicode字符跟无符号整数类似,大致对应一些拼写表示。所以,一个 NSCharacterSet +lowercaseCharacterSet 字符集与一个包含97到122范围的 NSIndexSet 是等价的。</p> <p>现在我们对理解 NSCharacterSet 的基本概念已经有了少许自信,让我们来看一些它的模式与反模式吧:</p> <h2>去掉空格</h2> <p>NSString -stringByTrimmingCharactersInSet: 是个你需要牢牢记住的方法。它经常会传入 NSCharacterSet +whitespaceCharacterSet 或 +whitespaceAndNewlineCharacterSet 来删除输入字符串的头尾的空白符号。</p> <p>需要重点注意的是,这个方法 仅仅 去除了 开头 和 结尾 的指定字符集中连续字符。这就是说,如果你想去除单词之间的额外空格,请看下一步。</p> <h2>挤压空格</h2> <p>假设你去掉字符串两端的多余空格之后,还想去除单词之间的多余空格,这里有个非常简便的方法:</p> <p>Objective-C</p> <pre> <code class="language-objectivec">NSString *string = @"Lorem ipsum dolar sit amet."; string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; NSArray *components = [string componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; components = [components filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self <> ''"]]; string = [components componentsJoinedByString:@" "];</code></pre> <p>首先,删除字符串首尾的空格;然后用 NSString -componentsSeparatedByCharactersInSet: 在空格处将字符串分割成一个 NSArray;再用一个 NSPredicate 去除空串;最后,用 NSArray -componentsJoinedByString: 用单个空格符将数组重新拼成字符串。注意:这种方法仅适用于英语这种用空格分割的语言。</p> <h2>从字符串解析数据</h2> <p>NSScanner 是个用以解析任意或半结构化的字符串的数据的类。当你为一个字符串创建一个扫描器时,你可以指定忽略哪些字符,这样可以避免那些字符以各种各样的方式被包含到解析出来的结果中。</p> <p>例如,你想从这样一个字符串中解析出开门时间:</p> <p>Text</p> <p>Mon-Thurs: 8:00 - 18:00</p> <p>Fri: 7:00 - 17:00</p> <p>Sat-Sun: 10:00 - 15:00</p> <p>你会 enumerateLinesUsingBlock: 并像这样用一个 NSScanner 来解析:</p> <p>SwiftObjective-C</p> <pre> <code class="language-objectivec">let skippedCharacters = NSMutableCharacterSet() skippedCharacters.formIntersectionWithCharacterSet(NSCharacterSet.punctuationCharacterSet()) skippedCharacters.formIntersectionWithCharacterSet(NSCharacterSet.whitespaceCharacterSet()) string.enumerateLines { (line, _) in let scanner = NSScanner(string: line) scanner.charactersToBeSkipped = skippedCharacters var startDay, endDay: NSString? var startHour: Int = 0 var startMinute: Int = 0 var endHour: Int = 0 var endMinute: Int = 0 scanner.scanCharactersFromSet(NSCharacterSet.letterCharacterSet(), intoString: &startDay) scanner.scanCharactersFromSet(NSCharacterSet.letterCharacterSet(), intoString: &endDay) scanner.scanInteger(&startHour) scanner.scanInteger(&startMinute) scanner.scanInteger(&endHour) scanner.scanInteger(&endMinute) }</code></pre> <p>我们首先从空格字符集和标点符号字符集的并集构造了一个 NSMutableCharacterSet。告诉 NSScanner 忽略这些字符以极大地减少解析这些字符的必要逻辑。</p> <p>scanCharactersFromSet: 传入字母字符集得到每项中一星期内的开始和结束(可选)的天数。scanInteger 类似地,得到下一个连续的整型值。</p> <p>NSCharacterSet 和 NSScanner 让你可以快速而充满自信地编码。这两者真是完美组合。</p> <p>NSCharacterSet 是基础类库中字符串处理系统中的一员,可能是最容易被用错或是误解的一员。在脑中记住这些模式与反模式,你将不仅能做一些很有用的诸如管理空格及从字符串中读信息之类的事情,更重要的是,你将避免误入歧途。</p> <p> </p> <p>来自:http://www.jianshu.com/p/0012a7ac5cdc</p> <p> </p>