43

我正在使用非常棘手的战斗方法:) 使字符串可以Fi?le*/ Name安全地用作文件名,例如File_Name. 我敢肯定有一种可可的方式来转换它。我敢肯定最好的地方就是在这里 :)

谢谢!

4

7 回答 7

68

这将根据 Ismail 的无效字符集删除文件名中任何位置的所有无效字符(我尚未验证他的设置有多完整)。

- (NSString *)_sanitizeFileNameString:(NSString *)fileName {
    NSCharacterSet* illegalFileNameCharacters = [NSCharacterSet characterSetWithCharactersInString:@"/\\?%*|\"<>"];
    return [[fileName componentsSeparatedByCharactersInSet:illegalFileNameCharacters] componentsJoinedByString:@""];
}

归功于 Peter N Lewis 使用 componentsSeparatedByCharactersInSet 的想法:
NSString - 仅转换为纯字母(即删除重音符号+标点符号)

于 2011-02-08T23:43:07.077 回答
16

除非您显式运行 shell 或使用诸如popenorsystem之类的函数隐式运行 shell,否则没有理由转义除了路径名分隔符之外的任何内容。

您可能还希望强制文件名不以句号开头(这会导致 Finder 隐藏文件),并且可能还应该强制文件名不为空且长度少于NAME_MAX字符*。

*syslimits.h表示字节,但如果你通过文件管理器,它是字符。我不确定哪个适合 Cocoa。

于 2009-08-15T10:26:06.347 回答
5

Swift 4 中的解决方案

extension String {
    var sanitizedFileName: String {
        return components(separatedBy: .init(charactersIn: "/\:\?%*|\"<>")).joined()
    }
}

用法:

"https://myurl.com".sanitizedFileName // = httpsmyurl.com
于 2017-10-21T15:32:55.230 回答
4
NSURL *fileURL = [NSURL fileURLWithPath:yourFilePath isDirectory:NO];

if (fileURL) {

    NSError *error;

    fileURL = [NSURL URLByResolvingAliasFileAtURL:fileURL options:(NSURLBookmarkResolutionWithoutUI | NSURLBookmarkResolutionWithoutMounting) error:&error];

}

转会前:

/Users/XXX/Desktop/~!@#$%^&*()_+`-={}|"<>?[]\;',.: {}<>:^ .png

转移后:

file:///Users/johnny/Desktop/~!@%23$%25%5E&*()_+%60-=%7B%7D%7C%22%3C%3E%3F%5B%5D%5C %3B',.:%20%20%7B%7D%3C%3E%5C:%5E%20.png

于 2015-12-29T07:32:04.350 回答
4

我迭代了johnboiles 的答案,转换为 Swift,并将其编写为扩展:

extension String {
    var stringForFilePath: String {
        // characterSet contains all illegal characters on OS X and Windows
        let characterSet = NSCharacterSet(charactersInString: "\"\\/?<>:*|")
        // replace "-" with character of choice
        return componentsSeparatedByCharactersInSet(characterSet).joinWithSeparator("-")
    }
}

从这里引用的非法字符集。

于 2016-09-11T11:27:23.153 回答
2

当然,必须有一个带有任意仇恨列表的 swift2 家伙(从其他答案中窃取)。那个人就是我:

func sanitizedString(string : String) -> String {
    // put anything you dislike in that set ;-)
    let invalidFsChars = NSCharacterSet(charactersInString: "/* <>?%|")
    let components = string.componentsSeparatedByCharactersInSet(invalidFsChars)
    return components.joinWithSeparator("")
}
于 2016-09-09T17:35:11.263 回答
-3

根据维基百科,应该从文件名中排除的最常见字符是:

/\?%*|"<>

http://en.wikipedia.org/wiki/文件名

鉴于此,并且由于替代解决方案中的倒置集操作可能很密集,对我来说,以下是一种更简洁的方法:

NSCharacterSet *invalidFsChars = [NSCharacterSet characterSetWithCharactersInString:@"/\\?%*|\"<>"];
NSString *scrubbed = [originalStr stringByTrimmingCharactersInSet:invalidFsChars];

这样,您仍然可以允许包含破折号等的文件名。

于 2011-01-09T03:35:33.150 回答