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

SwiftUI中字符串对比不生效:德语数字拼写匹配异常

问题描述
  • 随机整数转字符串后,验证用户输入时出现异常:控制台与屏幕显示的字符串视觉完全一致,但相等判断的if代码块未触发。
  • 土耳其语环境下功能正常,德语环境仅0-20的数字可正常匹配。例如数字23的德语拼写dreiundzwanzig,用户手动输入时无法触发相等判断,但将控制台输出的该字符串复制粘贴到TextField后,if代码块可正常执行。
相关代码

数字转字符串实现

final class NumberConfig {
    static var shared = NumberConfig()
    
    private init() { }
    
    func convertNumberToString(number: Int) -> String {
        let numberFormatter = NumberFormatter()
        numberFormatter.locale = Locale(identifier: "de-DE")
        numberFormatter.numberStyle = .spellOut
        if let text = numberFormatter.string(from: NSNumber(value: number)) {
            return text
        } else {
            return ""
        }
    }
}

视图逻辑代码

TextField("", text: $inputNumber)
.onChange(of: inputNumber) { value in
     isNumberEqual(inputNumber: value, number: stringNumber)
  }

func isNumberEqual(inputNumber: String, number: String) {
    print("\(inputNumber) - \(number)")
    
    if number == inputNumber {
        print("equal")
    } else {
        print("not equal")
    }
}

控制台输出表现

控制台打印的输入字符串与目标字符串视觉无差异,但判断结果始终为not equal;仅当复制目标字符串粘贴到输入框时,才会输出equal。

解决方案

问题根源

这是Unicode字符规范化形式不同导致的:NumberFormatter生成的德语数字字符串可能包含组合字符序列(比如基础字符+独立变音符号的Unicode码点组合),而用户手动输入的是预组合的单个Unicode字符。两者视觉一致,但底层编码序列不同,直接用==比较会判定为不相等。

修复代码

在字符串比较前,将两个字符串转换为相同的Unicode规范化形式(推荐使用NFC标准等价合成):

修改isNumberEqual函数:

func isNumberEqual(inputNumber: String, number: String) {
    print("\(inputNumber) - \(number)")
    
    // 转换为NFC规范化形式后再比较
    let normalizedInput = inputNumber.precomposedStringWithCanonicalMapping
    let normalizedTarget = number.precomposedStringWithCanonicalMapping
    
    if normalizedTarget == normalizedInput {
        print("equal")
    } else {
        print("not equal")
    }
}

调试辅助(可选)

如果需要确认字符编码差异,可以打印字符串的Unicode码点:

print("Input Unicode码点: \(inputNumber.unicodeScalars.map { $0.value })")
print("Target Unicode码点: \(number.unicodeScalars.map { $0.value })")

提前优化方案

也可以在生成转换后的字符串时直接做规范化,避免后续重复处理:

func convertNumberToString(number: Int) -> String {
    let numberFormatter = NumberFormatter()
    numberFormatter.locale = Locale(identifier: "de-DE")
    numberFormatter.numberStyle = .spellOut
    if let text = numberFormatter.string(from: NSNumber(value: number)) {
        // 生成时直接规范化为NFC形式
        return text.precomposedStringWithCanonicalMapping
    } else {
        return ""
    }
}

内容的提问来源于stack exchange,提问作者Ufuk Köşker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 23:42:05