带选项问题的StringByReplacingOccurrencesOfString

时间:2014-10-16 09:25:22

标签: ios objective-c nsstring

我想用其他字符串替换以下格式的字符串。此操作应在for循环中进行。

这里的fullString看起来像这样

There are some other things ... Child_name_13 and Child_name_12     there are some other things ...... Child_name_1 some other things ... Child_name_12 some other things.. Child_name_6 some other things ... Child_name_7

我想要做的是,更换" Child_name_1"," Child_name_12"," Child_name_7"具有相关子名称的等等从arrOfChildren返回。

我的方法如下。

for(int i=0; i<[arrOfChildren count]; i++){
    NSString *strChildName = [[arrOf15Children objectAtIndex:i] objectForKey:@"Name"];

    fullString = [fullString stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"child_name_%d",i+1] withString:strChildName options:NSCaseInsensitiveSearch range:NSMakeRange(0, [fullString length])];
}

问题是,我得到类似的输出(让我们说孩子的名字是Ben,Randy,Amil,Sanj,Paul,Mark,Ayen,Sid,Don,Yun,Xun,Xin,Nik,插孔)

There are some other things ... Ben3 and Ben2     there are some other things ...... Ben some other things ... Ben2 some other things..  Mark some other things ... Ayen

但我希望它像这样

There are some other things ...Nik and Xin  there are some other things ...... Ben some other things ... Xin some other things.. Mark some other things ... Ayen

我希望,你会得到这个问题。

6 个答案:

答案 0 :(得分:1)

问题与: [NSString stringWithFormat:@"child_name_%d",i+1]

因为 Child_name_1 将匹配 Child_name_13

这个问题有不同的解决方案。

1)多通道替换: 首先替换匹配数字大于等于10的项目,然后替换剩余的项目。

for(int i=9; i<[arrOfChildren count]; i++){
    NSString *strChildName = [[arrOf15Children objectAtIndex:i] objectForKey:@"Name"];

    fullString = [fullString stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"child_name_%d",i+1] withString:strChildName options:NSCaseInsensitiveSearch range:NSMakeRange(0, [fullString length])];
}
for(int i=0; i<max(9,[arrOfChildren count]); i++){
    NSString *strChildName = [[arrOf15Children objectAtIndex:i] objectForKey:@"Name"];

    fullString = [fullString stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"child_name_%d",i+1] withString:strChildName options:NSCaseInsensitiveSearch range:NSMakeRange(0, [fullString length])];
}

2)使用正则表达式NSRegularExpression)和[...] expression = @"child_name_[0-9]+[^0-9]"这样的表达式会更加健壮。

正则表达式有点棘手,但投入学习它们会让你在Stringhandling上获得“超级大国”!

答案 1 :(得分:0)

通过未知位数匹配将获得多个匹配。 'Child_name_10'中包含'Child_name_1',因此通过搜索'Child_name_1',您将获得多个匹配。

您可以通过'Child_name_1'(注释空格)进行匹配,但是您必须记住为要替换的名称添加空格。或者您可以在'Child_name_x'字符串中插入前导零(因此'Child_name_01'而不是'Child_name_1'等),然后将stringWithFormat更改为:

[NSString stringWithFormat:@"child_name_%02d",i+1]

如果您有超过99个孩子,请执行相同但三位数(因此%03d和'Child_name_001')等。

答案 2 :(得分:0)

你最好改为[NSString stringWithFormat:@&#34; child_name_%d&#34;,i + 1],使用空格,可以分隔前缀问题。

答案 3 :(得分:0)

也许 NSRegularExpression 可以帮到您:

NSString *string = @"Child_name_1 and Child_name_13 are friends";
NSArray *nameArray = @[@"Tom", @"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", @"11", @"Jerry"];

for (int i = 0; i < [nameArray count]; i++) {
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:[NSString stringWithFormat:@"\\bChild_name_%d\\b", i + 1] options:0 error:nil];
    if (regex != nil) {
        NSTextCheckingResult *firstMatch = [regex firstMatchInString:string options:0 range:NSMakeRange(0, string.length)];
        if (firstMatch) {
            NSRange resultRange = [firstMatch rangeAtIndex:0];
            string = [string stringByReplacingCharactersInRange:resultRange withString:[nameArray objectAtIndex:i]];
        }
    }
}

NSLog(@"result:%@", string);

您还可以查看 NSScanner :)

答案 4 :(得分:0)

<强>更新

刚刚编写了超级简单的解决方案。如果您知道字符串中的任何child_name包含的索引多于您拥有的名称数,即您的名称数组中有5个名称,则字符串中可能存在最大的child_name5和child_name6 +肯定缺席。

您只需反转您重复命名的方向

// only changed for statements, the rest is your code unchanged
for(int i=[arrOfChildren count]-1; i>=0; i--){
    NSString *strChildName = [[arrOf15Children objectAtIndex:i] objectForKey:@"Name"];

    fullString = [fullString stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"child_name_%d",i+1] withString:strChildName options:NSCaseInsensitiveSearch range:NSMakeRange(0, [fullString length])];
}

所以你替换所有child_name15,然后替换所有child_name14,依此类推child_name0。这就是我们如何破坏所有这些顶级强大的设施,我们忘记了应该如何编码。

旧回答:

你只需要一个正则表达式。您找到所有匹配项并将其替换为所需的名称。 可能有效的正则表达式示例:

child_name[0-9]*

您可以通过NSRegularExpression查找所有匹配项,并使用其他内容将其替换为适当的值。其他解决方案可能是使用组创建更复杂的正则表达式,并使用它们以更优雅的方式实现您想要的。

答案 5 :(得分:0)

  • 正则表达式解决了你的问题,我们必须使用整个字符串 \\ bchild_name_%d \\ b

检查以下代码

NSArray *arrOfChildren = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", @"four", @"five", @"six", @"seven", @"eight", @"nine", @"ten", @"leven", @"twe", @"thirt", @"fourten", @"fiftee", nil];

NSString *fullString = @"Child_name_1 Child_name_2 Child_name_3 Child_name_4 Child_name_5 Child_name_6 Child_name_7 Child_name_8 Child_name_9 Child_name_10 Child_name_11 Child_name_12  Child_name_13 Child_name_14 Child_name_15  ";

for(int i=0; i<[arrOfChildren count]; i++){
    NSString *strChildName = [arrOfChildren objectAtIndex:i];

    NSError *error = nil;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:[NSString stringWithFormat:@"\\bchild_name_%d\\b",i+1] options:NSRegularExpressionCaseInsensitive error:&error];

    fullString = [regex stringByReplacingMatchesInString:fullString options:0 range:NSMakeRange(0, [fullString length]) withTemplate:strChildName];

}

NSLog(@"full stirng %@", fullString);
  • 在您的代码中包含此内容

for(int i = 0; i&lt; [arrOfChildren count]; i ++){

NSString *strChildName = [[arrOf15Children objectAtIndex:i] objectForKey:@"Name"];

NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:[NSString stringWithFormat:@"\\bchild_name_%d\\b",i+1] options:NSRegularExpressionCaseInsensitive error:&error];

fullString = [regex stringByReplacingMatchesInString:fullString options:0 range:NSMakeRange(0, [fullString length]) withTemplate:strChildName];

}