2013-01-10 82 views
0

我想知道如何根据某些正则表达式([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”,
如何在NSString中替换多个正则表达式匹配?

意味着
A - > A#和A# - > B.
我也想保留任何东西存在我的基本和弦后,意思是:
上午 - > A#m。

我已经成功地扫描了字符串,并用新字符串替换了我想要的字符,但是我无法弄清楚如何在维持初始字符串空间的同时执行此操作。

所以总结的东西,基本上我想这样的:
“C A A#B”
成为这个:
“C#A#B C”

谢谢!

+0

这可能有所帮助:https://developer.apple.com/library/mac/#documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html –

回答

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包含匹配子字符串的所有范围。这些范围然后按相反的顺序(从上次匹配到第一次匹配)处理,以便突变字符串(可能会改变长度)不会影响其余范围的位置。

+0

非常感谢!它完美的作品。您的reverseObjectEnumerator for循环非常棒!我只是循环索引,然后追加。再次感谢! – user1644365

2

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

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

然后在各值在阵列中使用您选择任何逻辑执行映射/置换(即枚举用哈希表)。

最后只是加入的元素一起回来:

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

这将如何处理要求“我还想保留任何东西存在于我的基本和弦之后,意思是:Am - > A#m“?这并不意味着您必须测试每个组件是否*开始*必须替换的字符串?我认为这种情况我没有看到使用正则表达式的优势。 –