如何在去除标题字符串重复空格的同时保留首尾空格?
修复Swift字符串首尾空格保留+中间连续空格压缩的问题
你的原函数确实会丢失首尾空格,原因很直接:components(separatedBy: .whitespacesAndNewlines)会把开头/结尾的连续空格拆成空字符串,随后的filter { !$0.isEmpty }直接把这些空组件过滤掉了,导致首尾空格完全丢失。下面给你两种可行的修复方案:
方案一:正则表达式(简洁高效)
利用正则匹配仅中间的连续空白字符,替换成单个空格,这样首尾的空格会被完整保留。这种方法代码量最少,适合大多数场景:
func headlineFixer(headline: String) -> String { // 正则匹配:非空白字符后的连续空白,且后面跟着非空白字符 return headline.replacingOccurrences( of: "(?<=\\S)\\s+(?=\\S)", with: " ", options: .regularExpression ) }
测试示例:
- 输入:
" stack over flow is nice " - 输出:
" stack over flow is nice "
这个正则的逻辑是:只替换那些夹在两个非空白字符之间的连续空格,开头和结尾的空格因为不满足“前后都是非空白字符”的条件,所以不会被修改,完美符合你的需求。
方案二:手动控制首尾空格(精确灵活)
如果你需要精确保留首尾原始的空格数量(比如原输入开头有3个空格,输出也要保留3个),可以手动统计首尾空格数,处理中间内容后再拼接回去:
func headlineFixer(headline: String) -> String { // 统计开头连续空格的数量 let leadingSpaceCount = headline.prefix { $0.isWhitespace }.count // 统计结尾连续空格的数量 let trailingSpaceCount = headline.suffix { $0.isWhitespace }.count // 处理中间内容:去掉首尾空格后,合并连续空格为单个 let middleContent = headline.trimmingCharacters(in: .whitespacesAndNewlines) .components(separatedBy: .whitespacesAndNewlines) .filter { !$0.isEmpty } .joined(separator: " ") // 拼接首尾空格和处理后的中间内容 return String(repeating: " ", count: leadingSpaceCount) + middleContent + String(repeating: " ", count: trailingSpaceCount) }
这个方法的优势是完全复刻原始首尾的空格状态,不管是1个还是多个空格,都能精准保留。
内容的提问来源于stack exchange,提问作者DrainOpener
相关产品推荐
相关产品推荐

