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
相关产品推荐
相关产品推荐

