我正在尝试编写一个搜索NSString的方法,确定字符串中的单个单词是否长度超过6个字符,并用其他单词替换该单词(任意类似“hello”)。
我从一个长段开始,我需要最终得到一个NSString对象,其格式和间距不受查找和替换的影响。
答案 0 :(得分:10)
使用componentsSeparatedByString:
的简单解决方案存在一些微妙的问题:
假设替换词“ - ”是一个像...的字符串
“基本上”,D.H.C。得出的结论,
“bokanovskification包括一系列逮捕发展。”
......会导致......
- D.H.C. - 一系列 - 的 -
...虽然正确的输出是:
“ - ,”D.H.C。 - , - “ - - 一系列的 - 。”
幸运的是,在Cocoa中有一个更好但更简单的解决方案:-[NSString enumerateSubstringsInRange:options:usingBlock:]
它提供了对options
参数定义的子字符串的快速迭代。一种可能性是NSStringEnumerationByWords
,它枚举所有实际上是真实单词的子串(在当前语言环境中)。它甚至可以检测不使用分隔符(空格)来分隔单词的语言中的单个单词,例如日语。
Here's a simple demo project适用于行话文件(1.6 MB,237,239字)。它比较了三种不同的解决方案:
它的核心是替换循环:
NSMutableString *result = [NSMutableString stringWithCapacity:[originalString length]];
__block NSUInteger location = 0;
[originalString enumerateSubstringsInRange:(NSRange){0, [originalString length]}
options:NSStringEnumerationByWords | NSStringEnumerationLocalized | NSStringEnumerationSubstringNotRequired
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
if (substringRange.length > maxChar) {
NSString *charactersBetweenLongWords = [originalString substringWithRange:(NSRange){ location, substringRange.location - location }];
[result appendString:charactersBetweenLongWords];
[result appendString:replaceWord];
location = substringRange.location + substringRange.length;
}
}];
[result appendString:[originalString substringFromIndex:location]];
正如Monolo所指出的,建议的代码使用NSString
的长度来确定单词的字符数。至少可以说,这是一个值得怀疑的方法。实际上,字符串length
指定了用于对字符串进行编码的代码片段的数量,这个值通常与人类假定的字符数相符。
由于术语“字符”在各种上下文中具有不同的含义,并且OP没有指定使用哪种字符计数,所以我只保留代码。如果您想要不同的计数,请参阅讨论该主题的文档:
答案 1 :(得分:2)
从答案中可以看出,有几种方法可以实现您的目标,但我个人更喜欢使用NSString
类的stringByReplacingOccurrencesOfString:withString:options:range:
方法,该方法完全取代了子串另一个字符串。
在您的情况下,我们需要使用NSRegularExpressionSearch
选项,该选项将允许识别包含7个或更多字母的单词(即,当您声明时,超过6个字母)。
如果您使用\w
* 字符表达式,您将自动获得Unicode支持,因此它可以使用与Apple(实际上是ICU)支持的语言一样多的语言。
它是这样的:
NSString *stringWithLongWords = @"There are some words of extended length in this text. One of them is Escher's. They will be identified with a regular expression and changed for some arbitrary word.";
NSString *overSixCharsPattern = @"(?w)\\b[\\w]{7,}\\b";
NSString *replacementString = @"hello";
NSString *result = [stringWithLongWords stringByReplacingOccurrencesOfString: overSixCharsPattern
withString: replacementString
options: NSRegularExpressionSearch
range: NSMakeRange(0, stringWithLongWords.length)];
\b
表达式表示单词边界,确保整个单词匹配和替换。 w
修饰符使\b
使用更自然的单词边界定义。具体来说,它处理字符串“Escher's”,这是@NikolaiRuhe提到的例子。文档here,特别讨论了边界检测here。
另请注意,文字NSString
(即您直接在Objective-C源文件中键入的文字)在源代码中需要两个反斜杠才能在生成的字符串中生成一个反斜杠。
* 技术上\w
匹配单词字符,其中还包括正则表达式使用的定义中的数字。
答案 2 :(得分:-2)
试试这个。
NSString *str = @"Do any additional setup after loading the view, typically from a nib.";
NSMutableArray *array = [[str componentsSeparatedByString:@" "] mutableCopy];
for (int i = 0; i < [array count]; i++) {
NSString *str_ = [array objectAtIndex:i];
if ([str_ length] > 6)
[array replaceObjectAtIndex:i withObject:@"Hello"];
}
然后再添加它们
str = [array componentsJoinedByString:@" "];