You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何se_SV区域下CurrencyFormatter生成的字符串与手动字符串不相等?

为什么两个看似相同的字符串判断不相等?

这大概率是因为不可见的特殊字符差异,具体到瑞典语(se_SV)区域的货币格式化场景,最常见的问题出在这一点:

  • 千分位分隔符的类型:currencyFormatter生成的字符串里,千分位用的是非-breaking空格(Unicode编码U+00A0),而你手动输入的是普通空格(U+0020)。这两个字符肉眼看起来完全一样,但计算机识别它们是不同的字符,直接用==判断自然会返回false。

举个具体的代码示例:

let formatter = NumberFormatter()
formatter.locale = Locale(identifier: "se_SV")
formatter.numberStyle = .currency
let firstString = formatter.string(from: 1234.56) ?? ""
// firstString实际内容是 "1 234,56 kr" (注意:这里的空格是U+00A0)

let secondString = "1 234,56 kr" // 这里的空格是普通空格U+0020

怎么验证这个差异?

你可以把两个字符串转成Unicode标量值来直观查看:

print(firstString.unicodeScalars.map { $0.value })
print(secondString.unicodeScalars.map { $0.value })

对比输出结果,你会发现对应空格位置的数值一个是160(U+00A0),一个是32(U+0020),这就是判断不相等的核心原因。

怎么解决这个问题?

如果需要让两个字符串能正确匹配,有两种常用方式:

  1. 手动替换特殊空格:把格式化后的字符串里的非-breaking空格替换成普通空格
    let normalizedFirstString = firstString.replacingOccurrences(of: "\u{00A0}", with: " ")
    if normalizedFirstString == secondString {
        // 此时会返回true
    }
    
  2. 使用Unicode规范化方法:将字符串转为兼容的规范化形式
    let normalizedFirst = firstString.precomposedStringWithCanonicalMapping
    let normalizedSecond = secondString.precomposedStringWithCanonicalMapping
    if normalizedFirst == normalizedSecond {
        // 也能正确匹配
    }
    

另外补充一点:本地化场景下的字符串比较经常会遇到这类“肉眼不可见”的字符差异,比如不同语言的空格、连字符、引号等,直接用==判断前最好先做规范化处理哦。


内容的提问来源于stack exchange,提问作者Oleg Gordiichuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:15:26