15.2.3 可变字符串
NSMutableString类可以用来创建可以更改字符的字符串对象。因为该类是NSString类的子类,所以可以使用NSString类的所有方法。
讲述可变与不可变字符串对象时,我们讲到了更改字符串中的实际字符。任一可变或不可变字符串对象在程序执行期间,总是可以被设为完全不同的字符串对象。例如,考虑以下代码:
str1=@“This is a string”;
……
str1=[str1 substringFromIndex:5];
在这个例子中,首先将str1设置为一个常量字符串对象。后来在程序中将其设为一个子字符串。在这个例子中,str1可以声明为可变的字符串对象,也可以声明为不可变的字符串对象。一定要理解这一点。</p>
代码清单15-5展示了处理程序中可变字符串的几种方式。
代码清单15-5
//Basic String Operations-Mutable Strings
import<Foundation/NSObject.h>
import<Foundation/NSString.h>
import<Foundation/NSAutoreleasePool.h>
int main(int argc, char*argv[])
{
NSAutoreleasePool*pool=[[NSAutoreleasePool alloc]init];
NSString*str1=@“This is string A”;
NSStringsearch,replace;
NSMutableString*mstr;
NSRange substr;
//Create mutable string from nonmutable
mstr=[NSMutableString stringWithString:str1];
NSLog(@,mstr);
//Insert characters
[mstr insertString:@“mutable”atIndex:7];
NSLog(@,mstr);
//Effective concatentation if insert at end
[mstr insertString:@“and string B”atIndex:[mstr length]];
NSLog(@,mstr);
//Or can use appendString directly
[mstr appendString:@“and string C”];
NSLog(@,mstr);
//Delete substring based on range
[mstr deleteCharactersInRange:NSMakeRange(16,13)];
NSLog(@,mstr);
//Find range first and then use it for deletion
substr=[mstr rangeOfString:@“string B and”];
if(substr.location!=NSNotFound){
[mstr deleteCharactersInRange:substr];
NSLog(@,mstr);
}
//Set the mutable string directly
[mstr setString:@“This is string A”];
NSLog(@,mstr);
//Now lets replace a range of chars with another
[mstr replaceCharactersInRange:NSMakeRange(8,8)
withString:@“a mutable string”];
NSLog(@,mstr);
//Search and replace
search=@“This is”;
replace=@“An example of”;
substr=[mstr rangeOfString:search];
if(substr.location!=NSNotFound){
[mstr replaceCharactersInRange:substr
withString:replace];
NSLog(@,mstr);
}
//Search and replace all occurrences
search=@“a”;
replace=@“X”;
substr=[mstr rangeOfString:search];
while(substr.location!=NSNotFound){
[mstr replaceCharactersInRange:substr
withString:replace];
substr=[mstr rangeOfString:search];
}
NSLog(@,mstr);
[pool drain];
return 0;
}
代码清单15-5输出
This is string A
This is mutable string A
This is mutable string A and string B
This is mutable string A and string B and string C
This is mutable string B and string C
This is mutable string C
This is string A
This is a mutable string
An example of a mutable string
An exXmple of X mutXble string
声明
NSMutableString*mstr;
将mstr变量声明为一个变量,用来存储在程序执行过程中值可能更改的字符串对象。语句行
mstr=[NSMutableString stringWithString:str1];
将mstr设置为字符串对象,其内容是str1中的字符的副本,或“This is string A”。将stringWithString:方法发送给NSMutableString类时,返回了一个可变的字符串对象。而将stringWithString:方法发送给NSString类时,如代码清单15-5所示,则返回一个不可变的字符串对象。
insertString:atIndex:方法将指定的字符串插入接收者,插入点从指定的索引值开始。在这个例子中,在字符串的索引数7或者第8字符处插入字符串@“mutable”。与不可变字符串对象不同,这里没有返回值,因为被修改的是接收者,因为它是可变的字符串对象,所以可以这么做。
第二个insertString:atIndex:调用使用length方法将一个字符串插入另一个字符串结尾。appendString:使得这个任务变得简单一些。
通过使用deleteCharactersInRange:方法,可以删除字符串中指定数目的字符。对以下字符串
This is mutable string A and string B and string C
应用范围{16,13}时,从索引数16(或者字符串中的第17个字符)开始删除13个字符“string A and”。如图15-1所示。
图 15-1 字符串中的索引
代码清单15-5之后的rangeOfString:方法用来展示如何首先找到然后删除字符串。首先验证mstr中的确存在字符串@“string B and”,然后使用rangeOfString:方法返回的范围作为deleteCharactersInRange:方法的参数来删除这个字符串。
setString:方法可以用来直接设置可变字符串对象的内容。使用该方法将mstr设置为字符串@“This is string A”之后,replaceCharactersInRange:方法用另一个字符串来替换这个字符串中的部分字符。字符串的大小不必相同,可以使用大小相等或不等的字符串来替换另一个字符串。因此,语句
[mstr replaceCharactersInRange:NSMakeRange(8,8)
withString:@“a mutable string”];
的结果是8个字符“string A”被替换成16个字符“a mutable string”。
这个程序例子中的其余几行展示了如何执行搜索和替换操作。首先,在字符串mstr中(它包含@“This is a mutable string”)查找字符串@“This is”。如果在搜索字符串中找到该内容,就用字符串@“An example of”替换匹配的字符串。最终mstr中包含的字符串变为@“An example of a mutable string”。
然后,程序设置了一个循环来显示如何实现替换并全部替换操作。搜索字符串被设置为@“a”,替换字符串被设置为@“x”。
如果替换字符串还包括搜索字符串(例如,考虑使用字符串“aX”替换字符串“a”),那么将会陷入无限循环。
其次,如果替换字符串为空(也就是,不包含字符),那么将有效地删除所有搜索字符串。通过没有空格隔开的相邻引号可以指定空的常量字符串,如下所示:
replace=@“;
当然,如果只想删除字符串,则可以使用deleteCharactersInRange:方法,前面我们已经学过。最后,NSMutablestring类还包含一个名为replaceOccurrencesOfString:withString:
options:range:的方法,它可以用来执行搜索并全部替换。实际上,代码清单15-5中的while循环可以替换为如下一行代码:
[mstr replaceOccurrencesOfString:search
withString:replace
options:nil
range:NSMakeRange(0,[mstr length])];
这将获得相同的结果,并且避免了潜在的无限循环,因为该方法阻止这样的事情发生。