【问题标题】:Replacing numbers in an NSString with Objects from NSArray用 NSArray 中的对象替换 NSString 中的数字
【发布时间】:2011-09-29 13:56:55
【问题描述】:

在 UITextView 中,用户可以输入格式为 {{1}} 或 {{177}} 的数字。在预览字段中,就像这里一样,我想用 NSArray 中的值替换该模式,其中数字对应于数组中的行。

我有两个想法来解决这个问题:

  1. 用 NSRegularExpression 计算所有出现的次数,遍历它们并替换它们。
  2. 从 NSString 中创建一个单词数组并循环遍历该数组,替换出现的位置并将 NSString 重新组合在一起。

这两个选项中哪一个更高效、更可靠?还有其他方法吗?

-- 更新-- 这是查找模式的正则表达式:@"\\{\\{([1-9]|[1-9][0-9]|[1-9][0-9][0-9])\\}\\}"。如何在循环中使用它来替换模式?

【问题讨论】:

  • 你输入的字符串格式是什么?你能用 [NSString componentsSeparatedByString:] 吗?

标签: objective-c regex ios4 nsstring nsregularexpression


【解决方案1】:

这是使用NSRegularExpression的答案:

NSString * input = @"{{83}} fjsdkfjds {{122}}";

NSMutableString * strToMakeReplacements = [[NSMutableString alloc] initWithString:input];

NSError * error = nil;
NSRegularExpression * regex = [NSRegularExpression regularExpressionWithPattern:@"\\{\\{([1-9]|[1-9][0-9]|[1-9][0-9][0-9])\\}\\}" options:NSRegularExpressionCaseInsensitive    error:&error];

NSArray * matches = [regex matchesInString:input options:NSMatchingReportProgress range:NSMakeRange(0, [input length])];

for (int i = [matches count]-1; i>=0 ; i--) {
    NSTextCheckingResult * match = [matches objectAtIndex:i];

    NSRange matchRange = match.range;
    NSString * numString = [input substringWithRange:NSMakeRange(matchRange.location+2, matchRange.length-4)];
    NSInteger num = [numString intValue];

    NSString * replacementValue = [self replacementValueForNum:num]; // write this function yourself

    [strToMakeReplacements replaceCharactersInRange:match.range withString:replacementValue];
}

请注意,您需要转义正则表达式中的斜杠,使其变为\\{\\{([1-9]|[1-9][0-9]|[1-9][0-9][0-9])\\}\\}

【讨论】:

    【解决方案2】:

    我会使用第二种方法,因为它似乎比使用正则表达式更方便(尽管我承认对它们不是很有经验)。

    给定输入字符串NSString* input,我将过滤掉非数字字符,如下所示:

    NSCharacterSet* notNumbersSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
    NSArray * wholeNumbers = [input componentsSeparatedByCharactersInSet:notNumbersSet];
    

    现在循环遍历整数数组:

    for( NSString* numString in wholeNumbers ) {
        NSInteger num = [numString intValue];
        // ...
    }
    

    【讨论】:

    • 这个方法很好。但这不仅与数字有关,还与括号 {{x}} 的特定模式有关。这将如何运作?
    • 哦,我误会了。那么是的,你需要一个正则表达式来匹配你的模式。您需要查看 NSRegularExpression 文档页面。
    【解决方案3】:

    NSRegularExpression 方法是这样的——

    NSRegularExpression * expression = [NSRegularExpression regularExpressionWithPattern:@"\\{\\{(\\d+?)\\}\\}"
                                                                                 options:0
                                                                                   error:nil];
    NSMutableString * resultString = [aString mutableCopy];
    NSTextCheckingResult * result;
    NSUInteger location = 0;
    
    /* Get the first match in the remaining string to search */
    while ((result = [expression firstMatchInString:resultString options:0 range:NSMakeRange(location, [resultString length] - location)])) {
    
        /* Get the index of the array using the capture group 1 i.e. (\\d+?) */
        NSUInteger index = [[resultString substringWithRange:[result rangeAtIndex:1]] integerValue];
    
        /* Get the string that will replace the match */
        NSString * replacementString = [replacementStrings objectAtIndex:index];
    
        /* Replace the string */
        [resultString replaceCharactersInRange:result.range withString:replacementString];
    
        /* Skip to the end of the replaced string */
        location = result.range.location + [replacementString length];
    }
    

    由于我们的替换字符串来自一个数组,我怀疑我们有一个单一的语句解决方案。在这里,我们找到一个匹配项,适当地替换它,然后搜索字符串的其余部分以查找匹配项。我们重复这个没有更多的结果。

    【讨论】:

      猜你喜欢
      • 2015-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多