如何从文件扩展名中拆分文件名在Swift中?
鉴于包中文件的名称,我想加载到我的Swift应用程序的文件。 所以我需要使用这个方法:
let soundURL = NSBundle.mainBundle().URLForResource(fname, withExtension: ext)
无论出于何种原因,该方法需要从文件扩展名中分离出来的文件名。 很好,在大多数语言中很容易将两者分开。 但是到目前为止,我并没有发现它在Swift中是如此。
所以这里是我所拥有的:
var rt: String.Index = fileName.rangeOfString(".", options:NSStringCompareOptions.BackwardsSearch) var fname: String = fileName .substringToIndex(rt) var ext = fileName.substringFromIndex(rt)
如果我不在第一行包括打字,我会在后面两行发现错误。 有了它,我得到了第一行的错误:
Cannot convert the expression's type '(UnicodeScalarLiteralConvertible, options: NSStringCompareOptions)' to type 'UnicodeScalarLiteralConvertible'
我怎样才能从扩展名分割文件名? 有没有一些优雅的方式来做到这一点?
我对Swift感到兴奋,因为它好像比Objective C更优雅的语言。但现在我发现它有自己的麻烦。
第二次尝试:我决定做我自己的stringsearch方法:
func rfind(haystack: String, needle: Character) -> Int { var a = Array(haystack) for var i = a.count - 1; i >= 0; i-- { println(a[i]) if a[i] == needle { println(i) return i; } } return -1 }
但现在我得到一个错误在线var rt: String.Index = rfind(fileName, needle: ".")
:
'Int' is not convertible to 'String.Index'
如果没有演员,我会在后面两行中看到一个错误。
任何人都可以帮助我分裂这个文件名和扩展名?
这是与Swift 2,Xcode 7:如果你有扩展名已经在它的文件名,那么你可以传递完整的文件名作为第一个参数和空白string作为第二个参数:
let soundURL = NSBundle.mainBundle() .URLForResource("soundfile.ext", withExtension: "")
或者,也可以使用扩展参数。
如果你有一个URL,并且你想得到文件名称,那么你可以这样做:
soundURL.URLByDeletingPathExtension?.lastPathComponent
正如在评论中指出的,你可以使用这个。
let filename: NSString = "bottom_bar.png" let pathExtention = filename.pathExtension let pathPrefix = filename.stringByDeletingPathExtension
适用于Swift 3
和Swift 4
。 将此function添加到String
类:
extension String { func fileName() -> String { if let fileNameWithoutExtension = NSURL(fileURLWithPath: self).deletingPathExtension?.lastPathComponent { return fileNameWithoutExtension } else { return "" } } func fileExtension() -> String { if let fileExtension = NSURL(fileURLWithPath: self).pathExtension { return fileExtension } else { return "" } } }
例:
let file = "image.png" let fileNameWithoutExtension = file.fileName() let fileExtension = file.fileExtension()
在Swift 2.1 String.pathExtension不可用了。 相反,你需要通过NSURL转换来确定它:
NSURL(fileURLWithPath: filePath).pathExtension
解决schemeSwift 3
此解决scheme将适用于所有实例,不依赖于手动parsingstring。
let path = "/Some/Random/Path/To/This.Strange.File.txt" let fileName = URL(fileURLWithPath: path).deletingPathExtension().lastPathComponent Swift.print(fileName)
结果输出将是
This.Strange.File
在Swift中,您可以更改为NSString
以更快地获得扩展名:
extension String { func getPathExtension() -> String { return (self as NSString).pathExtension } }
在Swift 2.1中,似乎目前的做法是:
let filename = fileURL.URLByDeletingPathExtension?.lastPathComponent let extension = fileURL.pathExtension
Swift中的string肯定可以通过棘手的。 如果你想要一个纯粹的Swift方法,下面是我将如何做到这一点:
- 使用
find
来查找"."
的最后一个出现"."
在string的reverse
- 使用
advance
来获得"."
的正确索引"."
在原来的string中 - 使用
String
的subscript
函数,该函数使用IntervalType
来获取string - 把这个包装在一个函数中,返回一个可选的名字和扩展名的元组
像这样的东西:
func splitFilename(str: String) -> (name: String, ext: String)? { if let rDotIdx = find(reverse(str), ".") { let dotIdx = advance(str.endIndex, -rDotIdx) let fname = str[str.startIndex..<advance(dotIdx, -1)] let ext = str[dotIdx..<str.endIndex] return (fname, ext) } return nil }
这将用于:
let str = "/Users/me/Documents/Something.something/text.txt" if let split = splitFilename(str) { println(split.name) println(split.ext) }
哪些产出:
/Users/me/Documents/Something.something/text txt
或者,只需使用已有的NSString
方法,如pathExtension
和stringByDeletingPathExtension
。
Swift 3.0
let sourcePath = NSURL(string: fnName)?.pathExtension let pathPrefix = fnName.replacingOccurrences(of: "." + sourcePath!, with: "")
SWIFT 3.x最短原生解决scheme
let fileName:NSString = "the_file_name.mp3" let onlyName = fileName.deletingPathExtension let onlyExt = fileName.pathExtension
没有扩展或任何额外的东西(我已经testing。基于Swift 2的@ gabbler解决scheme)
Swift 3.x扩展解决scheme:
extension String { func lastPathComponent(withExtension: Bool = true) -> String { let lpc = self.nsString.lastPathComponent return withExtension ? lpc : lpc.nsString.deletingPathExtension } var nsString: NSString { return NSString(string: self) } } let path = "/very/long/path/to/filename_v123.456.plist" let filename = path.lastPathComponent(withExtension: false)
文件名常量现在包含“ filename_v123.456 ”
试试这个简单的Swift 4解决scheme
extension String { func stripExtension(_ extensionSeperator: Character = ".") -> String { let selfReversed = self.reversed() guard let extensionPosition = selfReversed.index(of: extensionSeperator) else { return self } return String(self[..<self.index(before: (extensionPosition.base.samePosition(in: self)!))]) } } print("hello.there.world".stripExtension()) // prints "hello.there"
一个更好的方法(或至less在Swift 2.0中的替代方法)是使用String pathComponents属性。 这将path名分割成一个string数组。 例如
if let pathComponents = filePath.pathComponents { if let last = pathComponents.last { print(" The last component is \(last)") // This would be the extension // Getting the last but one component is a bit harder // Note the edge case of a string with no delimiters! } } // Otherwise you're out of luck, this wasn't a path name!
无论出于何种原因,他们都摆脱了path扩展。
let str = "Hello/this/is/a/filepath/file.ext" let l = str.componentsSeparatedByString("/") let file = l.last?.componentsSeparatedByString(".")[0] let ext = l.last?.componentsSeparatedByString(".")[1]