在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/\~!@#\$\?\:\<\,.>\%^\&*()_+
-\=[]\\|\'\'\;.txt
@rmaddy 这不是重复的。我在问除了一遍又一遍地使用 stringByReplacingOccurrencesOfString 之外是否还有其他方法。
@Josh NSGod 是对的。转义的需要来自 shell(例如 bash)。 NSTask
不使用外壳。如果您要转义路径,没有人会转义它们,并且不会找到文件。
【参考方案1】:
正如NSTask
的setArguments:
方法的文档中所述,应该不需要做特殊的引用:
讨论
NSTask
对象同时转换 path 和 arguments 到适当的 C 风格字符串(使用 fileSystemRepresentation),然后通过argv[]
将它们传递给任务。 arguments 中的字符串不会进行 shell 扩展,因此您不需要 需要做特殊的引用,而shell变量,比如$PWD
,是没有的 解决了。
如果您觉得有必要,可否提供一些您想在NSTask
中运行的命令示例?
[更新]:我在 cmets 中看到您确实在使用 NSTask
来执行带有 -c
的 bash
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 是不是有任何基于非 Xcode 的命令行单元测试工具?
在objective-c中是不是有一个等效的sqlite .dump?
如何在 Objective-C 中检测未使用的方法和#import
Objective-C/CocoaHTTPServer - 是不是可以在没有任何 UI 的情况下将 CocoaHTTPServer 作为后台应用程序运行?