如何在NSString中替换多个正则表达式匹配?

时间:2013-01-10 20:35:38

标签: objective-c regex nsstring nsrange

我想知道如何根据一些正则表达式([A-G]#?)替换NSString的特定字符。 更具分析性的是,我有一个充满和弦和空格的NSString。     “C A A#B”。

我想要的是根据我制作的字典改变这些和弦:
    @“A”,@“A#”,
    @“A#”,@“B”,
    @“B”,@“C”,
    @“C”,@“C#”,
    @“C#”,@“D”,
    @“D”,@“D#”,
    @“D#”,@“E”,
    @“E”,@“F”,
    @“F”,@“F#”,
    @“F#”,@“G”,
    @“G”,@“G#”,
    @“G#”,@“A”,

意思是     A - > A#和A# - > B.
我还想保留在我的基本和弦之后存在的任何东西,意思是:
    Am - > A#米。

我已经成功扫描了字符串并用新字符串替换了我想要的元素,但是我无法弄清楚如何在保留初始字符串的空格时这样做。

总而言之,基本上我想要这个:
    “C A A#B”
成为这个:
    “C#A#B C”

谢谢!

2 个答案:

答案 0 :(得分:2)

考虑到你要用不同的值替换源字符串中的所有项目,我真的没有看到正则表达式的好处。您最好的选择可能是简单地将字符串解析为数组:

NSArray *stringArray = [myString componentsSeparatedByString:@" "];

然后使用您选择的任何逻辑(即带哈希表的枚举器)对数组中的每个值执行映射/替换。

最后只需将元素重新组合在一起:

NSString *joinedString = [mappedStringArray componentsJoinedByString:@" "];

答案 1 :(得分:1)

以下代码替换字典中的所有和弦,同时保留其他所有内容(以便“Am”被“A#m”替换为“)”:

NSDictionary *transposeDict = @{
    @"A": @"A#", @"A#": @"B", @"B": @"C", @"C": @"C#", @"C#": @"D",
    @"D": @"D#", @"D#": @"E", @"E": @"F", @"F": @"F#", @"F#": @"G",
    @"G": @"G#", @"G#": @"A"
};

NSString *melody = @" C A A# B   Am";
NSMutableString *transposedMelody = [melody mutableCopy];

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"([A-G]#?)"
                                                                       options:0
                                                                         error:NULL];

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

for (NSTextCheckingResult *match in [matches reverseObjectEnumerator]) {
    NSString *oldChord = [melody substringWithRange:match.range];
    NSString *newChord = transposeDict[oldChord];
    if (newChord != nil)
        [transposedMelody replaceCharactersInRange:match.range withString:newChord];
}


NSLog(@"old: %@", melody);
NSLog(@"new: %@", transposedMelody);

输出:

old:  C A A# B   Am
new:  C# A# B C   A#m

数组matches包含匹配子字符串的所有范围。然后以相反的顺序(从最后一个匹配到第一个匹配)处理这些范围,这样改变字符串(可能改变长度)不会影响剩余范围的位置。