我正在使用以下内容查找和替换文本作为用户键入textView
- (void)textViewDidChange:(UITextView *)textView {
if (textView != self.inputToolbar.contentView.textView) {
return;
}
NSRegularExpression *regEx;
NSDictionary *replacementRules = @{
@"cheese ": @"ham ",
@"cat ": @"dog ",
@"smile ": @"grin ",
};
// Build regular expression
NSMutableArray *patterns = [NSMutableArray arrayWithCapacity:
replacementRules.count];
for (NSString *str in replacementRules.allKeys) {
[patterns addObject:[NSString stringWithFormat:@"\\b(%@)\\b", str]];
}
NSString *reStr = [patterns componentsJoinedByString:@"|"];
regEx = [NSRegularExpression
regularExpressionWithPattern:reStr
options:NSRegularExpressionUseUnicodeWordBoundaries | NSRegularExpressionCaseInsensitive
error:NULL];
// our new string
NSMutableString *s = [NSMutableString new];
NSUInteger __block lastPos = 0;
[regEx enumerateMatchesInString:textView.text
options:kNilOptions
range:(NSRange){ 0, textView.text.length }
usingBlock:^(NSTextCheckingResult *result,
NSMatchingFlags flags,
BOOL *stop) {
// Append the string from _before_ the match
[s appendString:[textView.text substringWithRange:(NSRange){
lastPos, result.range.location - lastPos
}]];
lastPos = result.range.location + result.range.length;
// actually replace the string
NSString *captured = [textView.text substringWithRange:result.range];
[s appendString:replacementRules[captured]];
}];
// append rest of string, from after the last match
[s appendString:[textView.text substringWithRange:(NSRange){
lastPos, textView.text.length - lastPos
}]];
textView.text = s;
}
这对于少于8个左右的单词的字符串工作正常,但随着字符串变得越来越长,键入速度显着减慢并变得滞后(无论是否执行文本的查找和替换。)这会严重影响用户体验,有谁知道为什么会这样或如何解决它?
答案 0 :(得分:2)
您可以采取一些措施来提高速度。
首先,您需要将replacementRules
字典和相应的正则表达式的初始化从textViewDidChange
方法移开。每次最终用户键入或删除字符时构造字典和正则表达式都相当昂贵。
接下来,您应该更改正则表达式以减少捕获组的数量。目前,您的正则表达式如下所示:
\\b(cheese)\\b|\\b(cat)\\b|\\b(smile)\\b
您可以更改为等效的正则表达式
\\b(cheese|cat|smile)\\b
使正则表达式引擎的工作更容易。
最后,您应该制作一个标志,指示已发生替换,并从块内部进行设置。如果在您退出enumerateMatchesInString
方法时设置了 标记,则可以立即返回,并完全跳过[s appendString...]
部分。
答案 1 :(得分:0)
我不确定您是否需要使用正则表达式,因此如果您不这样做,此解决方案可能会更好一些。它会在按下空格之前输入最后一个单词,如果该单词匹配我们字典中的任何内容,我们会替换它,如果不是,我们会继续。
#import "ViewController.h"
@interface ViewController () <UITextViewDelegate>
@property (weak, nonatomic) IBOutlet UITextView *textView;
@property (strong, nonatomic) NSDictionary *words;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.words = @{ @"word": @"replace_word",
@"peter": @"replace_peter" };
}
- (void)textViewDidChange:(UITextView *)textView
{
NSString *lastCharacter = [textView.text substringWithRange:NSMakeRange([textView.text length]-1, 1)];
if([lastCharacter isEqualToString:@" "]) {
NSMutableArray *words = (NSMutableArray *)[textView.text componentsSeparatedByString:@" "];
NSString *lastWord = words[words.count - 2];
for (NSString *word in self.words.allKeys) {
if ([lastWord isEqualToString:word]) {
lastWord = self.words[word];
[words replaceObjectAtIndex:words.count - 2 withObject:lastWord];
textView.text = [words componentsJoinedByString:@" "];
break;
}
}
}
}
@end