在objective-c中是否有任何简单的方法在特殊字符前添加反斜杠?

时间:2013-03-19 20:26:46

标签: objective-c nsfilemanager nstask

注意:不确定为什么这被标记为重复,因为我明确表示我不想一遍又一遍地使用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

3 个答案:

答案 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