从 Swift 中的文件名中删除后缀

Remove suffix from filename in Swift

当试图从 filename 中删除后缀时,我只剩下后缀,这完​​全不是我想要的。

我在这里做错了什么(多少事):

let myTextureAtlas = SKTextureAtlas(named: "demoArt")

let filename = (myTextureAtlas.textureNames.first?.characters.split{[=11=] == "."}.map(String.init)[1].replacingOccurrences(of: "\'", with: ""))! as String

print(filename)

这会打印出 png,这是整个事情中最乏味的部分。

在 iOS 中,数组以 0 开头,并且您希望文件名不带扩展名,因此您使用 . 拆分了字符串,现在名称将存储在第一个对象中,扩展名存储在第二个

简单示例

let fileName = "demoArt.png"
let name = fileName.characters.split(".").map(String.init).first

您还可以使用 componentsSeparatedBy 拆分字符串,如下所示:

let fileName = "demoArt.png"
var components = fileName.components(separatedBy: ".")
if components.count > 1 { // If there is a file extension
  components.removeLast()
  return components.joined(separator: ".")
} else {
  return fileName
}

澄清一下:

fileName.components(separatedBy: ".")

将return一个由“demoArt”和“png”组成的数组。

您也可以使用正则表达式来提取最后一个点之前的所有部分:

let fileName = "test.png"
let pattern  = "^(.*)(\.[a-zA-Z]+)$"
let regexp = try! NSRegularExpression(pattern: pattern, options: [])
let extractedName = regexp.stringByReplacingMatches(in: fileName, options: [], range: NSMakeRange(0, fileName.characters.count), withTemplate: "")
print(extractedName) //test

有些人似乎忽略了一个文件名可以有多个句点,在那种情况下只有最后一个句点分隔文件扩展名。所以 this.is.a.valid.image.filename.jpg 和剥离扩展名应该 return this.is.a.valid.image.filename 而不是 this (因为这里会产生两个答案)或介于两者之间的任何其他内容。正则表达式的答案工作正常,但使用正则表达式有点矫枉过正(可能比使用简单的字符串处理慢 10 倍)。这是一个适用于所有人的通用函数:

func stripFileExtension ( _ filename: String ) -> String {
    var components = filename.components(separatedBy: ".")
    guard components.count > 1 else { return filename }
    components.removeLast()
    return components.joined(separator: ".")
}

print("1: \(stripFileExtension("foo"))")
print("2: \(stripFileExtension("foo.bar"))")
print("3: \(stripFileExtension("foo.bar.foobar"))")

输出:

foo
foo
foo.bar
let mp3Files = ["alarm.mp3", "bubbles.mp3", "fanfare.mp3"]
let ringtonsArray = mp3Files.flatMap { [=10=].components(separatedBy: ".").first }

@Confused with Swift 4 你可以这样做:

let fileName = "demoArt.png"
// or on your specific case:
// let fileName = myTextureAtlas.textureNames.first

let name = String(fileName.split(separator: ".").first!)
print(name)

此外,您还应该解包 first,但我不想让示例代码复杂化来解决您的问题。

顺便说一句,因为我最近也需要这个,如果你想删除一个你事先知道的特定后缀,你可以这样做:

let fileName = "demoArt.png"
let fileNameExtension = ".png"

if fileName.hasSuffix(fileNameExtension) {
    let name = fileName.prefix(fileName.count - fileNameExtension.count)
    print(name)
}

如果您不关心扩展名是什么。这是一个简单的方法。

let ss = filename.prefix(upTo: fileName.lastIndex { [=10=] == "." } ?? fileName.endIndex))

您可能希望在此之后将结果子字符串转换为字符串。随着 String(ss)

使用 .dropLast(k) 怎么样,其中 k 是您从后缀中删除的字符数?

否则,为了从文件名中正确删除路径的扩展名,我坚持你使用 URL 和 .deletingPathExtension().lastPathComponent

可能有点开销,但至少它是一个坚如磐石的 Apple API。

您可以return一个新字符串,从末尾删除一定数量的字符。

   let fileName = "demoArt.png"
   fileName.dropLast(4)

此代码returns "demoArt"

如果后缀是指路径扩展,则有一个方法:

let filename = "demoArt.png"
let name = (filename as NSString).deletingPathExtension
// name - "demoArt"

一个班轮:

let stringWithSuffixDropped = fileName.split(separator: ".").dropLast().joined(separator: ".")