Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c iOS Objective查找和替换/regex_Objective C_Regex - Fatal编程技术网

Objective c iOS Objective查找和替换/regex

Objective c iOS Objective查找和替换/regex,objective-c,regex,Objective C,Regex,当用户在文本视图中键入文本时,我使用以下命令查找和替换文本 - (void)textViewDidChange:(UITextView *)textView { if (textView != self.inputToolbar.contentView.textView) { return; } NSRegularExpression *regEx; NSDictionary *replacementRules = @{

当用户在文本视图中键入文本时,我使用以下命令查找和替换文本

- (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个左右单词的字符串,但是当字符串变长时,键入速度会大大减慢并变慢(无论是否执行文本的查找和替换)。这会极大地影响用户体验,有人知道为什么会出现这种情况,或者如何解决它吗?

有几种方法可以提高速度

首先,您需要将
replacementRules
字典和相应正则表达式的初始化从
textViewDidChange
方法移开。每次最终用户键入或删除字符时,构造一个字典和一个正则表达式是相当昂贵的

接下来,您应该更改正则表达式以减少捕获组的数量。当前,您的正则表达式如下所示:

\\b(cheese)\\b|\\b(cat)\\b|\\b(smile)\\b
您可以更改为等效的正则表达式

\\b(cheese|cat|smile)\\b
使正则表达式引擎的工作更容易


最后,您应该制作一个标志,指示已经发生了替换,并从块内部进行设置。如果退出
EnumerateMatchesInstalling
方法时未设置该标志,则可以立即返回,完全跳过
[s appendString…]
部分。

我不确定是否需要使用regex,因此如果不使用,该解决方案可能会更好一些。它获取在按下空格之前输入的最后一个单词,如果该单词与词典中的任何内容匹配,我们将替换它,如果不匹配,我们将继续

#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
#导入“ViewController.h”
@界面视图控制器()
@属性(弱、非原子)IBOutlet UITextView*textView;
@属性(强,非原子)NSDictionary*单词;
@结束
@实现视图控制器
-(无效)viewDidLoad{
[超级视图下载];
self.words=@{@“word”:@“替换word”,
@“彼得”:“替换彼得”};
}
-(无效)textViewDidChange:(UITextView*)textView
{
NSString*lastCharacter=[textView.text substringWithRange:NSMakeRange([textView.text length]-1,1)];
if([lastCharacter IsequalString:@”“){
NSMUTABLEARRY*字=(NSMUTABLEARRY*)[textView.text组件由字符串分隔:@”“;
NSString*lastWord=words[words.count-2];
for(self.words.allkey中的NSString*word){
if([lastWord IsequalString:word]){
lastWord=自我。单词[单词];
[words replaceObjectaIndex:words.count-2 with object:lastWord];
textView.text=[words componentsJoinedByString:@”“];
打破
}
}
}
}
@结束

如果有人键入“catch”或“cheeses”,你会怎么做?@Abizern
\\b
建议OP忽略它们。他正在使用
\b
重新登录,因此它应该只匹配
cat
对吗?你应该只检查他正在编辑的单词,而不是孔字符串。因此,您应该首先获取他刚刚键入的单词(在用户按下空格后),然后检查是否必须替换该单词。@aramusss OP还应该检查文本是否粘贴到文本字段中。