Swift中String.firstIndex(of: "\n")返回nil但字符串含\n的问题
解决RFID字符串中换行符索引查找问题
可行解决方案
针对你处理RFID阅读器CRLF(\r\n)格式数据的需求,推荐以下几种可靠方式定位换行符:
- 正则匹配任意换行序列
用正则表达式匹配CRLF、单独CR或LF,直接获取目标范围:
if let range = rfidstring.range(of: #"\r?\n"#, options: .regularExpression) { let lineEndIndex = range.lowerBound let rfid = rfidstring[..<lineEndIndex] // 提取完整RFID内容 }
- 手动遍历字符查找
直接遍历字符串每个字符,定位第一个CR或LF的位置:
var lineEndIndex: String.Index? for (offset, char) in rfidstring.enumerated() { if char == "\r" || char == "\n" { lineEndIndex = rfidstring.index(rfidstring.startIndex, offsetBy: offset) break } } if let index = lineEndIndex { let rfid = rfidstring[..<index] }
- 系统方法分割换行
若只需提取完整RFID内容,直接用系统方法自动识别所有标准换行符:
let components = rfidstring.components(separatedBy: .newlines) if let rfid = components.first, !rfid.isEmpty { // rfid即为完整的标签内容 }
奇怪现象的可能原因
你遇到的firstIndex(of: "\n")返回nil但contains("\n")为true的情况,大概率和Swift的字符处理逻辑有关:
- 调试器显示的
\r\n可能被组合成了扩展 grapheme 簇(特殊编码场景下的合并处理),导致单独查找\n作为Character时无法匹配,但contains是基于Unicode标量检测的,所以能识别到\n的存在。 - 少数情况下可能是调试器显示优化,实际字符串中的换行符并非标准U+000A(LF),而是其他等价Unicode标量,但这种情况极少。
你可以通过以下代码打印字符串的Unicode标量,确认实际内容:
print(Array(rfidstring.unicodeScalars)) // 正常CRLF会输出:["9","0","0","0","8","3","0","0","0","0","2","0","7","5","8", "\r", "\n"]
内容的提问来源于stack exchange,提问作者Kenny Wyland
相关产品推荐
相关产品推荐

