注意:不确定为什么这被标记为重复,因为我明确表示我不想一遍又一遍地使用stringByReplacingOccurrencesOfString。
我对特殊字符文件名有疑问。
我已经实现了一个程序,因此当你打开一个文件或多个文件时,程序将读取所有这些文件名和本地路径并将它们存储到NSMutableArray中。这部分完美无缺。
我的程序还需要使用NSTask来操作这些文件。但问题是,有时文件名将包含特殊字符,例如/Users/josh/Desktop/Screen Shot 2013-03-19 at 2.05.06 PM.png
。
我必须用反斜杠和空格替换空格
NSString *urlPath = [[self url] path];
urlPath = [urlPath stringByReplacingOccurrencesOfString:@"(" withString:@"\\("];
urlPath = [urlPath stringByReplacingOccurrencesOfString:@")" withString:@"\\)"];
urlPath = [urlPath stringByReplacingOccurrencesOfString:@" " withString:@"\\ "];
至:/Users/josh/Desktop/Screen\ Shot\ 2013-03-19\ at\ 2.05.06\ PM.png
这样我就可以正确操作文件了。
(
和)
相同。我还需要在此之前添加反斜杠。
但是有太多特殊字符。即
/Users/josh/Desktop/~!@#$?:<,.>%^&*()_+`-={}[]\|'';.txt
我需要改为:
/Users/josh/Desktop/\~\!@\#\$\?\:\<\,.\>\%^\&\*\(\)_+\`-\=\{\}\[\]\\\|\'\'\;.txt
更不用说其他特殊字符(即重音符)
是否有任何简单的方法可以在每个特殊字符前添加反斜杠,因为我不想一遍又一遍地调用stringByReplacingOccurrencesOfString
。
答案 0 :(得分:1)
我认为您可以使用NSRegularExpressionSearch
搜索。
它看起来像这样
+ (NSString *) addBackslashes: (NSString *) string
{
// First convert the name string to a pure ASCII string
NSData *asciiData = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *asciiString = [[[NSString alloc] initWithData:asciiData encoding:NSASCIIStringEncoding] lowercaseString];
// Define the characters that we will replace
NSString *searchCharacters = @"PUT IN ALL OF YOUR SPECIAL CHARACTERS HERE";
// example NSString *searchCharacters = @"!@#$%&*()";
// replace them
NSString *regExPattern = [NSString stringWithFormat:@"[%@]", searchCharacters];
string = [asciiString stringByReplacingOccurrencesOfString:regExPattern withString: [NSString stringWithFormat:@"\\%@", regExPattern] options:NSRegularExpressionSearch range:NSMakeRange(0, asciiString.length)];
return string;
}
答案 1 :(得分:1)
正如NSTask
针对setArguments:
方法的文档中所述,不需要做特别引用:
<强>讨论强>
NSTask
对象转换路径和字符串 参数到适当的C风格字符串(使用 fileSystemRepresentation)在通过argv[]
将它们传递给任务之前。 参数中的字符串不会进行shell扩展,因此您不会 需要进行特殊引用,而shell变量(例如$PWD
)则不需要 解决。
如果您认为有必要,请提供一些您希望在NSTask
中运行的命令的示例吗?
[更新]:我在评论中看到您确实使用NSTask
执行bash
shell -c
,这是我想知道的。我通常使用NSTask
直接执行命令而不是通过shell,如下所示:
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/bin/ls"];
[task setArguments:[NSArray arrayWithObjects:@"-l", self.url.path, nil]];
您能否提供一个更准确的实例命令示例?例如,您是否将一系列命令组合在一起?也许可以有另一种方法来实现相同的结果,而无需使用bash
shell ...
答案 2 :(得分:0)
您可以维护一组需要转义的字符串,并使用NSScanner通过迭代源字符串来构建新字符串,每次找到有问题的字符时,首先将\\
添加到目标字符串中继续处理下一个字符。
NSString *sourceString = @"/Users/josh/Desktop/\"Screen Shot\" 2013-03-19 at 2\\05\\06 PM.png";
NSMutableString *destString = [@"" mutableCopy];
NSCharacterSet *escapeCharsSet = [NSCharacterSet characterSetWithCharactersInString:@" ()\\"];
NSScanner *scanner = [NSScanner scannerWithString:sourceString];
while (![scanner isAtEnd]) {
NSString *tempString;
[scanner scanUpToCharactersFromSet:escapeCharsSet intoString:&tempString];
if([scanner isAtEnd]){
[destString appendString:tempString];
}
else {
[destString appendFormat:@"%@\\%@", tempString, [sourceString substringWithRange:NSMakeRange([scanner scanLocation], 1)]];
[scanner setScanLocation:[scanner scanLocation]+1];
}
}
NSLog(@"\n%@\n%@", sourceString, destString);
结果:
/Users/josh/Desktop/Screen Shot 2013-03-19 at 2.05.06 PM.png
/Users/josh/Desktop/Screen\ Shot\ 2013-03-19\ at\ 2.05.06\ PM.png