Chaque exemple de découpage de chaînes dans Swift supprime les espaces blancs de début et de fin, mais comment peut-on supprimer uniquement les espaces de fin ?
Par exemple, si j'ai une chaîne:
" example "
Comment puis-je me retrouver avec:
" example"
Toutes les solutions que j'ai trouvées affichent trimmingCharacters(in: CharacterSet.whitespaces)
, mais je souhaite conserver les principaux espaces.
RegEx est une possibilité, ou une plage peut être dérivée pour déterminer l’index des caractères à supprimer, mais je ne semble pas pouvoir trouver une solution élégante pour cela.
Avec des expressions régulières:
let string = " example "
let trimmed = string.replacingOccurrences(of: "\\s+$", with: "", options: .regularExpression)
print(">" + trimmed + "<")
// > example<
\s+
correspond à un ou plusieurs espaces, et $
correspond à la fin de la chaîne.
Dans Swift 4
var trailingSpacesTrimmed: String {
var newString = self
while newString.hasSuffix(" ") {
newString = String(newString.dropLast())
}
return newString
}
Cette courte extension de chaîne Swift 3 utilise les options .anchored et .backwards de rangeOfCharacter, puis s’appelle de manière récursive si elle doit être bouclée. Comme le compilateur attend un CharacterSet en tant que paramètre, vous pouvez simplement fournir la statique lors de l'appel, par exemple. "1234 ".trailing(.whitespaces)
retournera "1234"
. (Je n'ai pas fait les timings, mais je m'attendrais à plus rapide que les regex.)
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
}
}
Dans Foundation
, vous pouvez obtenir des plages d'index correspondant à une expression régulière. Vous pouvez également remplacer les sous-plages. En combinant cela, nous obtenons:
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
}
}
}
Vous pouvez également avoir une version en mutation de ceci:
import Foundation
extension String {
mutating func trimTrailingWhitespace() {
if let trailingWs = self.range(of: "\\s+$", options: .regularExpression) {
self.replaceSubrange(trailingWs, with: "")
}
}
}
Si nous comparons avec \s*
(comme Martin R. l’a fait au début), nous pouvons ignorer la garde if let
et forcer le déroulé facultatif, car il y aura toujours une correspondance. Je pense que c'est mieux car c'est évidemment sûr, et le reste si vous changez l'expression rationnelle. Je n'ai pas pensé à la performance.
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()
}
}
C'est un peu hacky: D
let message = " example "
var trimmed = ("s" + message).trimmingCharacters(in: .whitespacesAndNewlines)
trimmed = trimmed.substring(from: trimmed.index(after: trimmed.startIndex))
Sans expression régulière, il n’existe aucun moyen direct d’atteindre cet objectif. Vous pouvez également utiliser la fonction ci-dessous pour obtenir le résultat souhaité:
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)
}
Vous pouvez utiliser cette fonction de la manière suivante: -
let str = " Himanshu "
print(removeTrailingSpaces(with : str))
Swift 4
extension String {
var trimmingTrailingSpaces: String {
if let range = rangeOfCharacter(from: .whitespacesAndNewlines, options: [.anchored, .backwards]) {
return String(self[..<range.lowerBound]).trimmingTrailingSpaces
}
return self
}
}