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

Posted

技术标签:

【中文标题】在objective-c中是不是有任何简单的方法可以在特殊字符前添加反斜杠?【英文标题】:in objective-c is there any easy way to add backslash in front of special characters?在objective-c中是否有任何简单的方法可以在特殊字符前添加反斜杠? 【发布时间】:2013-03-19 20:26:46 【问题描述】:

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

【问题讨论】:

基于这个 SO 问题:***.com/questions/2931942/nsstring-backslash-escaping 这似乎是目前最好的方法之一:/ 你能举例说明你想在NSTask中运行什么类型的命令吗?不需要对文件路径中的任何内容进行转义,因为它们通常直接以argv 的形式传递,并且不会进行 shell espansion。 @NSGod 我一直认为需要逃避。 IE。如果您打开终端并拖动文件名包含特殊代码的文件,终端将自动添加转义反斜杠。这就是我发现的方式。 /Users/josh/Desktop/~!@#$?:%^&*()_+-=[]\|'';.txt I need to change to: /Users/josh/Desktop/\~!@#\$\?\:\&lt;\,.&gt;\%^\&amp;*()_+-\=[]\\|\'\'\;.txt @rmaddy 这不是重复的。我在问除了一遍又一遍地使用 stringByReplacingOccurrencesOfString 之外是否还有其他方法。 @Josh NSGod 是对的。转义的需要来自 shell(例如 bash)。 NSTask 不使用外壳。如果您要转义路径,没有人会转义它们,并且不会找到文件。 【参考方案1】:

正如NSTasksetArguments: 方法的文档中所述,应该不需要做特殊的引用:

讨论

NSTask 对象同时转换 patharguments 到适当的 C 风格字符串(使用 fileSystemRepresentation),然后通过argv[] 将它们传递给任务。 arguments 中的字符串不会进行 shell 扩展,因此您不需要 需要做特殊的引用,而shell变量,比如$PWD,是没有的 解决了。​​

如果您觉得有必要,可否提供一些您想在NSTask 中运行的命令示例?

[更新]:我在 cmets 中看到您确实在使用 NSTask 来执行带有 -cbash shell,我对此感到疑惑。我一般使用NSTask直接执行命令而不是通过shell,像这样:

NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/bin/ls"];
[task setArguments:[NSArray arrayWithObjects:@"-l", self.url.path, nil]];

您能否给出一个更准确的示例来说明您要运行的实际命令?例如,您是否将一系列命令连接在一起?也许可能有另一种方法可以在不需要使用bash shell 的情况下实现相同的结果...

【讨论】:

NSTask *task = [[NSTask alloc] init]; [task setLaunchPath:@"/bin/bash"]; NSString *argument = [NSString stringWithFormat:@"ls -l %@", self.url.path]; [task setArguments:[NSArray arrayWithObjects:@"-c", argument, nil]]; 所以如果我只通过 self.url.path 而不添加反斜杠,它将无法工作。但正如我所说,有太多字符需要添加反斜杠并继续使用 stringByReplacingOccurrencesOfString 似乎效率不高 更好的解决方案是不使用外壳。为什么不将“/bin/ls”作为启动路径,将 [“-l”, self.url.path] 作为启动参数? 我记得从 ***.com 上读过一篇文章,如果 NSTask 有太多参数,请使用 /bin/bash。 IE。 | grep 或 |哦。这就是我在这里使用 /bin/bash 的原因。我的 NSTask 的一些参数很短(即 ls -l),但有些涉及 grep 和 awk。 我想我会使用一些 NSTask 而不是使用 bash。感谢您的帮助【参考方案2】:

我认为您可以使用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;

【讨论】:

使用正则表达式也是一个好办法,比多次调用stringByReplacingOccurrencesOfString要清晰得多,谢谢【参考方案3】:

您可以维护一组需要转义的字符串,并使用 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

【讨论】:

以上是关于在objective-c中是不是有任何简单的方法可以在特殊字符前添加反斜杠?的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C 中的 int 是不是有默认值 1?

Objective-C 是不是有任何基于非 Xcode 的命令行单元测试工具?

在objective-c中是不是有一个等效的sqlite .dump?

如何在 Objective-C 中读取键盘输入

如何在 Objective-C 中检测未使用的方法和#import

Objective-C/CocoaHTTPServer - 是不是可以在没有任何 UI 的情况下将 CocoaHTTPServer 作为后台应用程序运行?