iOS文件名中允许使用哪些字符?
我正在寻找一种方法来确保一个string可以用作iOS下的文件名。 我目前在删除不兼容字符的代码部分。 我想知道如果我做对了。
NSString *filename = @"A file name"; fileName = [fileName stringByTrimmingCharactersInSet: [NSCharacterSet controlCharacterSet]]; fileName = [fileName stringByTrimmingCharactersInSet: [NSCharacterSet newlineCharacterSet]];
我也想知道是否已经有一个方法来validation一个string作为文件名。
感谢您的build议!
首先,你正在使用错误的方法。 修剪string只会删除string开头和结尾的字符。
你在找什么更像是:
fileName = [fileName stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
然而,这是一个不太理想的解决scheme,因为您必须为要排除的每个字符执行此操作,所以您可能希望继续查找或编写自己的操作string的方法。
iOS是基于UNIX的,因此我认为它几乎支持文件名中的任何字符。 UNIX允许使用空格<,>,|,\,:,(,),&,以及通配符,如? 和*,用\符号引用或转义。 但是,我不会在我的文件名中使用任何这些字符。 实际上,我将文件名中的字符限制为“a” – “z”,“0” – “9”,“_”和“。”。
使用RegEx:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^a-zA-Z0-9_]+" options:0 error:nil]; filename = [regex stringByReplacingMatchesInString:filename options:0 range:NSMakeRange(0, filename.length) withTemplate:@"-"];
我不得不使用包含基本字母数字字符以外的其他字符的文件名在本地保存远程文件。 我使用下面的方法去掉潜在的无效字符,当使用URLWithString生成NSURL时,确保它是文件系统的有效文件名:
filename = [[filename componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsJoinedByString:@"" ]; filename = [[filename componentsSeparatedByCharactersInSet:[NSCharacterSet illegalCharacterSet]] componentsJoinedByString:@"" ]; filename = [[filename componentsSeparatedByCharactersInSet:[NSCharacterSet symbolCharacterSet]] componentsJoinedByString:@"" ]; fileURLString = [NSTemporaryDirectory() stringByAppendingPathComponent:filename]; fileURL = [NSURL URLWithString:fileURLString];
您可能还需要先使用以下方法testing碰撞错误:
[[NSFileManager defaultManager] fileExistsAtPath:[fileURL absoluteString]]
由于在这个问题中我没有看到允许使用字符的列表,但是这个问题想要一个带有这些字符的列表,我在这个主题上增加了一些细节。
首先,我们需要知道iOS设备使用的文件系统是什么。 使用多个在线来源,这似乎是HFSX这是HFS +区分大小写的版本。 并且包含一个链接供参考: https : //apple.stackexchange.com/questions/83671/what-filesystem-does-ios-use
现在我们知道文件系统是什么,我们可以查找哪些字符是不允许的。 这些似乎是:冒号(:)和斜杠(/)。 以下链接供参考: http : //www.comentum.com/File-Systems-HFS-FAT-UFS.html
有这个信息和其他人写在这个线程我个人喜好从文件名删除不允许的字符是以下的Swift代码:
filename = "-".join(filename.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet())) filename = "-".join(filename.componentsSeparatedByCharactersInSet(NSCharacterSet.illegalCharacterSet())) filename = "-".join(filename.componentsSeparatedByCharactersInSet(NSCharacterSet.controlCharacterSet())) filename = "-".join(filename.componentsSeparatedByString(":")) filename = "-".join(filename.componentsSeparatedByString("/"))
我不喜欢RegEx方法的原因是它似乎对我太严格了。 我不想限制我的用户只能拉丁字符。 他们不妨使用一些中文,西里尔文或其他任何他们喜欢的东西。
快乐的编码!
我觉得这是更清洁,可能更高性能。 这是基于天使Naydenov的解决scheme,但首先构造与所有无效字符的字符集,然后调用components(separatedBy:)
一次。
Swift 3
var invalidCharacters = CharacterSet(charactersIn: ":/") invalidCharacters.formUnion(.newlines) invalidCharacters.formUnion(.illegalCharacters) invalidCharacters.formUnion(.controlCharacters) let newFilename = originalFilename .components(separatedBy: invalidCharacters) .joined(separator: "")
Swift 2
let invalidCharacters = NSMutableCharacterSet(charactersInString: ":/") invalidCharacters.formUnionWithCharacterSet(NSCharacterSet.newlineCharacterSet()) invalidCharacters.formUnionWithCharacterSet(NSCharacterSet.illegalCharacterSet()) invalidCharacters.formUnionWithCharacterSet(NSCharacterSet.controlCharacterSet()) let filename = originalFilename .componentsSeparatedByCharactersInSet(invalidCharacters) .joinWithSeparator("")
我很满意这个解决scheme:
NSString *testString = @"This*is::/legal.😀,?縦書き 123"; NSString *result = [[[testString componentsSeparatedByCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"length > 0"]] componentsJoinedByString:@"-"];
输出:
"This-is-legal-縦書き-123"
这个巫术是什么?
让我把它分成多行,所以很清楚发生了什么事情:
NSString *testString = @"This*is::/legal.😀,?縦書き 123"; // Get a character set for everything that's NOT alphanumeric. NSCharacterSet *nonAlphanumericCharacterSet = [[NSCharacterSet alphanumericCharacterSet] invertedSet]; // Split the string on each non-alphanumeric character, thus removing them. NSArray *cleanedUpComponentsWithBlanks = [testString componentsSeparatedByCharactersInSet:nonAlphanumericCharacterSet]; // Filter out empty strings ("length" is a KVO-compliant property that the predicate can call on each NSString in the array). NSArray *cleanedUpComponentsWithoutBlanks = [cleanedUpComponentsWithBlanks filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"length > 0"]]; // Put the components back together and join them with a "-". NSString *result = [cleanedUpComponentsWithoutBlanks componentsJoinedByString:@"-"];
请享用!
我想出了以下解决scheme。 到目前为止工作很好。
import Foundation extension String { func removeUnsupportedCharactersForFileName() -> String { var cleanString = self ["?", "/", "\\", "*"].forEach { cleanString = cleanString.replacingOccurrences(of: $0, with: "-") } return cleanString } } let a = "***???foo.png" let validString = a.removeUnsupportedCharactersForFileName()