从 NSString 中去除非字母数字字符
Posted
技术标签:
【中文标题】从 NSString 中去除非字母数字字符【英文标题】:Strip Non-Alphanumeric Characters from an NSString 【发布时间】:2009-11-01 04:40:06 【问题描述】:我正在寻找一种从NSString
中去除非字母数字字符的快速简便的方法。可能是使用NSCharacterSet
的东西,但我很累,似乎没有返回一个只包含字符串中的字母数字字符的字符串。
【问题讨论】:
+1 是正确标记为 cocoa 而不是 objective-c 的 5% 的问题之一 【参考方案1】:我们可以通过拆分然后加入来做到这一点。组件SeparatedByCharactersInSet 需要 OS X 10.5+:
NSCharacterSet *charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
NSString *strippedReplacement = [[someString componentsSeparatedByCharactersInSet:charactersToRemove] componentsJoinedByString:@""];
【讨论】:
什么是字母数字字符?例如。德语“元音变音”,如 ä、ö 或 ü 是否会包含在集合中,因此不会被修剪? 要处理重音字符,您需要创建一个 NSMutableCharacterSet,它是 alphanumericCharacterSet 和 nonBaseCharacterSet 的并集,并将其反转trimmedReplacement
具有误导性。在所有 ios NSString 调用中,trimmed 表示从开始到结束。我可以建议 occurrencesReplacement 或 strippedReplacement 代替吗?
@Erik,将包括变音符号。这使得它无法用于文件名:(
@datayeah 不用担心,只需根据pubs.opengroup.org/onlinepubs/9699919799/basedefs/… 更改第一行以反转“便携式文件名字符集”:NSCharacterSet *charactersToRemove = [[NSCharacterSet characterSetWithCharactersInString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"] invertedSet];
【参考方案2】:
在 Swift 中,componentsJoinedByString
被 join(...)
替换,所以这里它只是用空格替换非字母数字字符。
let charactersToRemove = NSCharacterSet.alphanumericCharacterSet().invertedSet
let strippedReplacement = " ".join(someString.componentsSeparatedByCharactersInSet(charactersToRemove))
对于 Swift2 ...
var enteredByUser = field.text .. or whatever
let unsafeChars = NSCharacterSet.alphanumericCharacterSet().invertedSet
enteredByUser = enteredByUser
.componentsSeparatedByCharactersInSet(unsafeChars)
.joinWithSeparator("")
如果您只想删除一个字符,例如删除所有返回...
enteredByUser = enteredByUser
.componentsSeparatedByString("\n")
.joinWithSeparator("")
【讨论】:
【参考方案3】:我最终做的是创建一个 NSCharacterSet 和我发现的 -invertedSet
方法(奇怪的是,多睡一小时对文档阅读能力有什么作用)。这是代码 sn-p,假设 someString
是您要从中删除非字母数字字符的字符串:
NSCharacterSet *charactersToRemove =
[[ NSCharacterSet alphanumericCharacterSet ] invertedSet ];
NSString *trimmedReplacement =
[ someString stringByTrimmingCharactersInSet:charactersToRemove ];
trimmedReplacement
然后将包含someString
的字母数字字符。
【讨论】:
仅供参考,stringByTrimmingCharactersInSet:仅删除字符串开头和结尾的字符。也许这就是你想要的。 嗯,好点子,肯。我不知道。它仍然可以满足我的需求,但很高兴知道。【参考方案4】:已接受答案的 Swift 3 版本:
let unsafeChars = CharacterSet.alphanumerics.inverted
let myStrippedString = myString.components(separatedBy: unsafeChars).joined(separator: "")
【讨论】:
【参考方案5】:清理类别
我有一个方法调用 stringByStrippingCharactersInSet:
和 stringByCollapsingWhitespace
可能很方便直接插入。
@implementation NSString (Cleanup)
- (NSString *)clp_stringByStrippingCharactersInSet:(NSCharacterSet *)set
return [[self componentsSeparatedByCharactersInSet:set] componentsJoinedByString:@""];
- (NSString *)clp_stringByCollapsingWhitespace
NSArray *components = [self componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
components = [components filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self <> ''"]];
return [components componentsJoinedByString:@" "];
@end
【讨论】:
【参考方案6】:Swift 5,扩展:
extension String
/// Will strip all non alpha characters from a string
public var alpha: String
return components(separatedBy: CharacterSet.alphanumerics.inverted).joined()
【讨论】:
【参考方案7】:这是Cameron’s category 的 Swift 版本作为扩展:
extension String
func stringByStrippingCharactersInSet(set:NSCharacterSet) -> String
return (self.componentsSeparatedByCharactersInSet(set) as NSArray).componentsJoinedByString("")
func stringByCollapsingWhitespace() -> String
var components:NSArray = self.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
let predicate = NSPredicate(format: "self <> ''", argumentArray: nil)
components = components.filteredArrayUsingPredicate(predicate)
return components.componentsJoinedByString(" ")
【讨论】:
"".join(componentsSeparatedByCharactersInSet(set))
更好。【参考方案8】:
我认为简单的循环将是更快的执行时间:
@implementation NSString(MyUtil)
- (NSString*) stripNonNumbers
NSMutableString* res = [NSMutableString new];
//NSCharacterSet *numericSet = [NSCharacterSet decimalDigitCharacterSet];
for ( int i=0; i < self.length; ++i )
unichar c = [self characterAtIndex:i];
if ( c >= '0' && c <= '9' ) // this looks cleaner, but a bit slower: [numericSet characterIsMember:c])
[res appendFormat:@"%c", c];
return res;
@end
【讨论】:
【参考方案9】:这是比提供的答案更有效的方法
+ (NSString *)alphanumericString:(NSString *)s
NSCharacterSet * charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
NSMutableString * ms = [NSMutableString stringWithCapacity:[s length]];
for (NSInteger i = 0; i < s.length; ++i)
unichar c = [s characterAtIndex:i];
if (![charactersToRemove characterIsMember:c])
[ms appendFormat:@"%c", c];
return ms;
或作为一个类别
@implementation NSString (Alphanumeric)
- (NSString *)alphanumericString
NSCharacterSet * charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
NSMutableString * ms = [NSMutableString stringWithCapacity:[self length]];
for (NSInteger i = 0; i < self.length; ++i)
unichar c = [self characterAtIndex:i];
if (![charactersToRemove characterIsMember:c])
[ms appendFormat:@"%c", c];
return ms;
@end
【讨论】:
以上是关于从 NSString 中去除非字母数字字符的主要内容,如果未能解决你的问题,请参考以下文章