web-dev-qa-db-ja.com

Swift 3の文字列の末尾から末尾の空白のみを削除します

Swiftで先頭と末尾の両方の空白を削除しますが、どのように末尾のみ空白を削除できますか?

たとえば、文字列がある場合:

_"    example  "
_

どうすれば終わることができます:

_"    example"
_

私が見つけたすべてのソリューションはtrimmingCharacters(in: CharacterSet.whitespaces)を示していますが、先頭の空白を保持したいです。

RegExは可能性であるか、削除する文字のインデックスを決定するための範囲を導き出すことができますが、これに対するエレガントな解決策を見つけることはできないようです。

27
Jason Sturges

正規表現の場合:

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

\s+は1つ以上の空白文字と一致し、$は、文字列の末尾に一致します。

34
Martin R

In Swift 4&&Swift 5

このコードは、後続の改行も削除します。 Character構造体のメソッド.isWhitespaceに基づいて動作します

var trailingSpacesTrimmed: String {
    var newString = self

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

    return newString
}
13
Demosthese

この短い文字列の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
    }
}
7
Obliquely

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
Raphael

Handy String extension In 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
TimBigDev

それは少しハッキーです:D

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

正規表現がなければ、それを達成する直接的な方法はありません。あるいは、以下の関数を使用して必要な結果を得ることができます。

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))
2
Himanshu

Swift 4

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