26 regex string cocoa objective-c nsstring
我正在尝试比较名称,没有任何标点符号,空格,重音等.目前我正在做以下事情:
-(NSString*) prepareString:(NSString*)a {
//remove any accents and punctuation;
a=[[[NSString alloc] initWithData:[a dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES] encoding:NSASCIIStringEncoding] autorelease];
a=[a stringByReplacingOccurrencesOfString:@" " withString:@""];
a=[a stringByReplacingOccurrencesOfString:@"'" withString:@""];
a=[a stringByReplacingOccurrencesOfString:@"`" withString:@""];
a=[a stringByReplacingOccurrencesOfString:@"-" withString:@""];
a=[a stringByReplacingOccurrencesOfString:@"_" withString:@""];
a=[a lowercaseString];
return a;
}
Run Code Online (Sandbox Code Playgroud)
但是,我需要为数百个字符串执行此操作,我需要提高效率.有任何想法吗?
Pet*_*wis 80
NSString* finish = [[start componentsSeparatedByCharactersInSet:[[NSCharacterSet letterCharacterSet] invertedSet]] componentsJoinedByString:@""];
Run Code Online (Sandbox Code Playgroud)
Pet*_*sey 39
在使用任何这些解决方案之前,不要忘记使用decomposedStringWithCanonicalMapping分解任何重音字母.例如,这将把é(U + 00E9)变成e(U + 0065 U + 0301).然后,当您删除非字母数字字符时,将保留非重音字母.
这很重要的原因是你可能不希望,例如,"dän"和"dün"*被视为相同.如果你删除了所有重音字母,正如其中一些解决方案可能会做的那样,你最终会得到"dn",所以这些字符串将相等.
因此,您应该首先分解它们,以便您可以去除重音并留下字母.
*来自德国的例子.感谢Joris Weimar提供它.
Sop*_*ert 14
在类似的问题上,Ole Begemann建议使用stringByFoldingWithOptions:我相信这是最好的解决方案:
Run Code Online (Sandbox Code Playgroud)NSString *accentedString = @"ÁlgeBra"; NSString *unaccentedString = [accentedString stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:[NSLocale currentLocale]];根据要转换的字符串的性质,您可能希望设置固定的区域设置(例如英语),而不是使用用户的当前区域设置.这样,您可以确保在每台机器上获得相同的结果.
小智 7
比起BillyTheKid18756的答案有一个重要的精确度(由Luiz纠正但在代码的解释中并不明显):
不要使用 stringWithCString作为删除重音的第二步,它可以在字符串的末尾添加不需要的字符,因为NSData不是以NULL结尾的(因为stringWithCString需要它).或者使用它并向NSData添加一个额外的NULL字节,就像Luiz在他的代码中所做的那样.
我认为更简单的答案是替换:
NSString *sanitizedText = [NSString stringWithCString:[sanitizedData bytes] encoding:NSASCIIStringEncoding];
Run Code Online (Sandbox Code Playgroud)
通过:
NSString *sanitizedText = [[[NSString alloc] initWithData:sanitizedData encoding:NSASCIIStringEncoding] autorelease];
Run Code Online (Sandbox Code Playgroud)
如果我收回BillyTheKid18756的代码,这里是完整正确的代码:
// The input text
NSString *text = @"BûvérÈ!@$&%^&(*^(_()-*/48";
// Defining what characters to accept
NSMutableCharacterSet *acceptedCharacters = [[NSMutableCharacterSet alloc] init];
[acceptedCharacters formUnionWithCharacterSet:[NSCharacterSet letterCharacterSet]];
[acceptedCharacters formUnionWithCharacterSet:[NSCharacterSet decimalDigitCharacterSet]];
[acceptedCharacters addCharactersInString:@" _-.!"];
// Turn accented letters into normal letters (optional)
NSData *sanitizedData = [text dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
// Corrected back-conversion from NSData to NSString
NSString *sanitizedText = [[[NSString alloc] initWithData:sanitizedData encoding:NSASCIIStringEncoding] autorelease];
// Removing unaccepted characters
NSString* output = [[sanitizedText componentsSeparatedByCharactersInSet:[acceptedCharacters invertedSet]] componentsJoinedByString:@""];
Run Code Online (Sandbox Code Playgroud)
如果您要比较字符串,请使用以下方法之一.不要试图改变数据.
- (NSComparisonResult)localizedCompare:(NSString *)aString
- (NSComparisonResult)localizedCaseInsensitiveCompare:(NSString *)aString
- (NSComparisonResult)compare:(NSString *)aString options:(NSStringCompareOptions)mask range:(NSRange)range locale:(id)locale
Run Code Online (Sandbox Code Playgroud)
您需要考虑用户区域设置来执行使用字符串写入的内容,尤其是名称之类的内容.在大多数语言中,ä和å等字符除了看起来相似之外并不相同.它们本质上是不同的字符,其含义与其他字符不同,但实际的规则和语义对于每个语言环境都是不同的.
比较和排序字符串的正确方法是考虑用户的语言环境.1990年的其他任何东西都是天真的,错误的.停止这样做.
如果您尝试将数据传递到不支持非ASCII的系统,那么这只是一件错误的事情.将其作为数据blob传递.
加上规范化你的琴弦(参见Peter Hosey的帖子)预先制作或分解,基本上选择一个标准化的形式.
- (NSString *)decomposedStringWithCanonicalMapping
- (NSString *)decomposedStringWithCompatibilityMapping
- (NSString *)precomposedStringWithCanonicalMapping
- (NSString *)precomposedStringWithCompatibilityMapping
Run Code Online (Sandbox Code Playgroud)
不,它不像我们想象的那么简单和容易.是的,它需要明智和谨慎的决策.(以及一些非英语语言经验有帮助)
考虑使用RegexKit 框架。你可以这样做:
NSString *searchString = @"This is neat.";
NSString *regexString = @"[\W]";
NSString *replaceWithString = @"";
NSString *replacedString = [searchString stringByReplacingOccurrencesOfRegex:regexString withString:replaceWithString];
NSLog (@"%@", replacedString);
//... Thisisneat
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
26261 次 |
| 最近记录: |