在Swift 3中仅修剪字符串末尾的空格

时间:2017-01-10 09:18:21

标签: swift string swift3

Swift中修剪字符串的每个示例都会删除前导和尾随空格,但只能删除空白?

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

"    example  "

我怎样才能最终:

"    example"

我找到的每个解决方案都显示trimmingCharacters(in: CharacterSet.whitespaces),但我想保留领先的空白。

RegEx是一种可能性,或者可以导出一个范围来确定要删除的字符的索引,但我似乎无法为此找到一个优雅的解决方案。

12 个答案:

答案 0 :(得分:32)

使用正则表达式:

\s+

$匹配一个或多个空白字符,select date, max(case when filename like 'contracts%' then importId end) as importId_contracts max(case when filename like 'accounts%' then importId end) as importId_accounts from Imports where date = '2017-01-05' group by date 匹配 字符串的结尾。

答案 1 :(得分:11)

在Swift 4& Swift 5

此代码还将删除尾随的新行。 它的工作原理基于Character结构的方法.isWhitespace

var trailingSpacesTrimmed: String {
    var newString = self

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

    return newString
}

答案 2 :(得分:7)

这个简短的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
    }
}

答案 3 :(得分:6)

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后卫并强制解开可选项,因为总会有匹配。我认为这更好,因为它显然是安全的,并且如果你改变正则表达式仍然是安全的。我没有考虑表现。

答案 4 :(得分:5)

Handy String extension 在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 :(得分:3)

有点hacky:D

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

答案 6 :(得分: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))

答案 7 :(得分:2)

快捷键4

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

答案 8 :(得分:2)

每次从末尾插入时都无需创建新字符串。

extension String {

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

这对集合进行操作,并且仅将结果转换回一次字符串。

答案 9 :(得分:0)

Demostheseanswer是解决此问题的有用方法,但是效率不是很高。这是对他们答案的升级,改为扩展StringProtocol,并利用Substring消除重复复制的需要。

extension StringProtocol {

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

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

        return view
    }
}

答案 10 :(得分:0)

使用Swift 4和5的单行解决方案

作为Swift和iOS编程的初学者,我非常喜欢上面带有while循环的@demosthese解决方案,因为它很容易理解。但是,示例代码似乎比必要的时间更长。以下内容使用了基本相同的逻辑,但将其实现为单行while循环。

// Remove trailing spaces from myString
while myString.last == " " { myString = String(myString.dropLast()) }

这也可以使用.isWhitespace属性来编写,就像@demosthese的解决方案一样,如下所示:

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

这具有优点(或缺点,取决于您的观点),它不仅删除空格,而且删除所有类型的空格(根据Apple文档),还包括换行符,尤其是以下字符:

  • “ \ t”(U + 0009字符制表符)
  • ““(U + 0020 SPACE)
  • U + 2029参数分隔符
  • U + 3000理想空间

注意:尽管.isWhitespace是布尔值,但由于可选项{{的链接)最终成为可选的while,因此它不能直接在?循环中使用。 1}}属性,如果String(或集合)为空,则返回.last。自nil起,== true逻辑就解决了这个问题。

尤其是,我很想获得一些反馈。如果有人发现这种简单的单行方法有任何问题或弊端。

答案 11 :(得分:0)

斯威夫特 5

extension String {

   func trimTrailingWhiteSpace() -> String {
       guard self.last == " " else { return self }
    
       var tmp = self
       repeat {
           tmp = String(tmp.dropLast())
       } while tmp.last == " "
    
       return tmp
}

}

相关问题