Swift中阿拉伯语字符串执行替换与空白修剪后计数仍为1的原因分析
问题原因与解决办法
嘿,我来帮你拆解这个坑人的小问题——你遇到的情况根本不是逻辑错了,而是被一个看不见的Unicode控制字符给绊住了!
到底是什么在搞鬼?
你的原始字符串 "باب " 里,看起来在"باب"后面的是个空白,但实际上那是个右向左标记(RLM,Unicode编码U+200F)。这个字符是用来调整从右到左书写的文本(比如阿拉伯语、希伯来语)的显示方向的,本身完全不可见,但它不属于.whitespacesAndNewlines包含的字符范围。
所以你的代码执行流程是这样的:
- 替换掉
"باب"之后,字符串里就只剩这个RLM字符了 trimmingCharacters(in: .whitespacesAndNewlines)对它完全无效,因为它不是空白或换行- 最后字符串里就剩这一个控制字符,所以
count自然是1,不是0。
怎么解决?
有两种靠谱的处理方式,看你的场景选:
方案一:精准干掉RLM
如果你确定只需要处理这个特定的控制字符,可以把它加入到要修剪的字符集合里:
let str = "باب " let cleanedStr = str.replacingOccurrences(of: "باب", with: "") .trimmingCharacters(in: CharacterSet.whitespacesAndNewlines.union(CharacterSet(charactersIn: "\u{200F}"))) print(cleanedStr.count) // 现在输出0啦
方案二:批量清理所有控制字符
如果你的场景里可能出现其他类似的隐形控制字符,不如直接过滤掉所有Unicode控制字符:
let str = "باب " let cleanedStr = str.replacingOccurrences(of: "باب", with: "") .trimmingCharacters(in: .whitespacesAndNewlines) .filter { !$0.isControlCharacter } print(cleanedStr.count) // 同样输出0
怎么验证这个隐形字符?
你可以打印字符串的Unicode标量来确认它的存在:
let str = "باب " for scalar in str.unicodeScalars { print(scalar, scalar.value) }
运行后你会看到输出里明确有U+200F,这就是那个藏起来的捣蛋鬼。
内容的提问来源于stack exchange,提问作者sheko
相关产品推荐
相关产品推荐

