在NSString中查找并替换长单词?

Hen*_*ale 0 objective-c nsstring

我正在尝试编写一个搜索NSString的方法,确定字符串中的单个单词是否长度超过6个字符,并用其他单词替换该单词(任意类似"hello").

我从一个长段开始,我需要最终得到一个NSString对象,其格式和间距不受查找和替换的影响.

Nik*_*uhe 10

为什么另一个答案

使用以下简单解决方案存在一些微妙的问题componentsSeparatedByString::

  1. 标点符号不作为单词分隔符处理.
  2. 只删除空格字符(换行符,制表符)的空格.
  3. 在长字符串上浪费了大量内存.
  4. 这很慢.

假设替换词" - "是一个字符串...

"基本上,"DHC总结道,
"bokanovskification包括一系列逮捕发展."

......会导致......

- DHC - - 一系列的 -

...而正确的输出将是:

" - ,"DHC - ,
" - - 一系列 - ."

幸运的是,Cocoa中有一个更好,更简单的解决方案: -[NSString enumerateSubstringsInRange:options:usingBlock:]

它提供了对options参数定义的子字符串的快速迭代.一种可能性是NSStringEnumerationByWords枚举所有实际上是真实单词的子串(在当前语言环境中).它甚至可以检测不使用分隔符(空格)来分隔单词的语言中的单个单词,例如日语.

比较解决方案

这是一个简单的演示项目,适用于行话文件(1.6 MB,237,239字).它比较了三种不同的解决方

  1. componentsSeparatedByString:270毫秒
  2. enumerateSubstringsInRange:125毫秒
  3. stringByReplacingOccurrencesOfString,如@Monolo所述:200毫秒

履行

它的核心是替换循环:

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]];
Run Code Online (Sandbox Code Playgroud)

警告

正如Monolo所指出的,建议的代码使用NSString's长度来确定单词的字符数.至少可以说,这是一个值得怀疑的方法.实际上,字符串length指定了用于对字符串进行编码的代码片段的数量,这个值通常与人类假定的字符数量有关.

由于术语"字符"在各种上下文中具有不同的含义,并且OP没有指定使用哪种字符计数,因此我只需保留代码.如果您想要不同的计数,请参阅讨论该主题的文档: