在Swift 3中仅删除字符串末尾的空格

37

在 Swift 中修剪字符串的每个示例都会删除前导和尾随空格,但是如何仅删除尾随空格?

例如,如果我有一个字符串:

"    example  "

我该如何最终得到:

"    example"

我找到的每个解决方案都使用 trimmingCharacters(in: CharacterSet.whitespaces),但是我想保留前导空格。

正则表达式是一种可能性,或者可以派生出一个范围来确定要删除的字符的索引,但我似乎找不到一个优雅的解决方案。


12个回答

50

通过正则表达式:

let string = "    example  "
let trimmed = string.replacingOccurrences(of: "\\s+$", with: "", options: .regularExpression)
print(">" + trimmed + "<")
// >    example<

\s+ 匹配一个或多个空白字符,$ 匹配字符串的结尾。


是的,那可能更好。我不知道是否已经明确,但这也需要 Foundation - Raphael
3
不应该在有更好的工具时使用正则表达式,应该使用字符集。请参考 Obliquely 的答案 - ChrisJF
3
它可以完成任务,而不需要递归或创建中间字符串。 - Martin R

24

在 Swift 4 和 Swift 5 中

这段代码还会移除末尾的空行。它基于 Character 结构体的方法 .isWhitespace 运作。

var trailingSpacesTrimmed: String {
    var newString = self

    while newString.last?.isWhitespace == true {
        newString = String(newString.dropLast())
    }

    return newString
}

为了更高效和通用的实现,请参考以下链接:https://dev59.com/c1gR5IYBdhLWcg3wO7Q0#59238738 - Andreas detests censorship

10

这个短小的 Swift 3 字符串扩展使用 rangeOfCharacter.anchored.backwards选项,如果需要循环,它会递归调用自身。由于编译器期望参数为一个CharacterSet,因此在调用时可以直接提供静态值,例如 "1234 ".trailing(.whitespaces) 将返回 "1234"。(我没有进行计时,但预计比正则表达式更快。)

extension String {
    func trailingTrim(_ characterSet : CharacterSet) -> String {
        if let range = rangeOfCharacter(from: characterSet, options: [.anchored, .backwards]) {
            return self.substring(to: range.lowerBound).trailingTrim(characterSet)
        }
        return self
    }
}

8

Demosthese答案是一个有用的解决方案,但并不特别高效。这是对他们答案的升级,扩展了StringProtocol,利用Substring来消除重复复制的需要。

extension StringProtocol {

    @inline(__always)
    var trailingSpacesTrimmed: Self.SubSequence {
        var view = self[...]

        while view.last?.isWhitespace == true {
            view = view.dropLast()
        }

        return view
    }
}

7
Foundation中,您可以获取与正则表达式匹配的索引范围。您还可以替换子范围。将它们结合起来,我们得到:
import Foundation
extension String {
    func trimTrailingWhitespace() -> String {
        if let trailingWs = self.range(of: "\\s+$", options: .regularExpression) {
            return self.replacingCharacters(in: trailingWs, with: "")
        } else {
            return self
        }
    }
}

您还可以拥有这个的可变版本:
import Foundation
extension String {
    mutating func trimTrailingWhitespace() {
        if let trailingWs = self.range(of: "\\s+$", options: .regularExpression) {
            self.replaceSubrange(trailingWs, with: "")
        }
    }
}

如果我们匹配 \s*(就像 Martin R. 一开始做的那样),我们可以跳过 if let 守卫并强制解包可选项,因为总会有一个匹配。我认为这更好,因为它显然是安全的,并且如果您更改正则表达式,它仍然是安全的。我没有考虑性能。

6

方便的字符串扩展 在 Swift 4 中

extension String {

    func trimmingTrailingSpaces() -> String {
        var t = self
        while t.hasSuffix(" ") {
          t = "" + t.dropLast()
        }
        return t
    }

    mutating func trimmedTrailingSpaces() {
        self = self.trimmingTrailingSpaces()
    }

}

5

Swift 4

extension String {
    var trimmingTrailingSpaces: String {
        if let range = rangeOfCharacter(from: .whitespacesAndNewlines, options: [.anchored, .backwards]) {
            return String(self[..<range.lowerBound]).trimmingTrailingSpaces
        }
        return self
    }
}

4
无需每次从末尾删除时创建新字符串。
extension String {

    func trimRight() -> String {
        String(reversed().drop { $0.isWhitespace }.reversed())
    }
}

这个操作针对集合进行,只有在操作结束后才将结果转换回字符串。


3

这有点“hacky”(即不太正规) :D


let message = "    example  "
var trimmed = ("s" + message).trimmingCharacters(in: .whitespacesAndNewlines)
trimmed = trimmed.substring(from: trimmed.index(after: trimmed.startIndex))

2

如果没有正则表达式,就没有直接的方法来实现这一点。或者,您可以使用下面的函数来实现所需的结果:

func removeTrailingSpaces(with spaces : String) -> String{

        var spaceCount = 0
        for characters in spaces.characters{
            if characters == " "{
                print("Space Encountered")
                spaceCount = spaceCount + 1
            }else{
                break;
            }
        }

        var finalString = ""
        let duplicateString = spaces.replacingOccurrences(of: " ", with: "")
        while spaceCount != 0 {
          finalString = finalString + " "
            spaceCount = spaceCount - 1
        }

        return (finalString + duplicateString)


    }

您可以按照以下方式使用此功能:
 let str = "   Himanshu  "
 print(removeTrailingSpaces(with : str))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接