Swift中修剪字符串的每个示例都会删除前导和尾随空格,但只能删除空白?
例如,如果我有一个字符串:
" example "
我怎样才能最终:
" example"
我找到的每个解决方案都显示trimmingCharacters(in: CharacterSet.whitespaces)
,但我想保留领先的空白。
RegEx是一种可能性,或者可以导出一个范围来确定要删除的字符的索引,但我似乎无法为此找到一个优雅的解决方案。
答案 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)
Demosthese的answer是解决此问题的有用方法,但是效率不是很高。这是对他们答案的升级,改为扩展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和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文档),还包括换行符,尤其是以下字符:
注意:尽管.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
}
}