使用俄语字符解析字符串时出现问题

Problem parsing Strings with Russian chars

我正在使用一个旧的 objectiveC 例程(我们称之为 oldObjectiveCFunction),它解析一个字符串来分析每个字符。在分析完 chars 之后,它将那个 String 分成多个 String,然后 returns 将它们放入一个名为 *functions 的数组中。这是旧函数如何进行字符串解析的超级简化示例:

NSMutableArray *functions = [NSMutableArray new];
NSMutableArray *components = [NSMutableArray new];
NSMutableString *sb = [NSMutableString new];
char c;
int sourceLen = source.length;
int index = 0;

while (index < sourceLen) {
    c = [source characterAtIndex:index];
    //here do some random work analyzing the char 
    [sb appendString:[NSString stringWithFormat:@"%c",c]];
    if (some condition){
        [components addObject:(NSString *)sb];                 
        sb = [NSMutableString new];
        [functions addObject:[components copy]];
    }
}

稍后,我将使用 Swift 代码获取每个 * 函数字符串:

let functions = oldObjectiveCFunction(string) as? [[String]]
functions?.forEach({ (function) in
    var functionCopy = function.map { [=11=] }
    for index in 0..<functionCopy.count {
       let string = functionCopy[index]
    }
}

问题在于,它可以完美地处理普通字符串,但如果字符串包含俄语名称,则如下所示:

РАЦИОН

输出,我的let string变量的内容,是这样的:

 \u{10}&\u{18}\u{1e}\u{1d}

我怎样才能得到相同的俄语字符串而不是那个?

我试过这样做:

let string2 = String(describing: string?.cString(using: String.Encoding.utf8))

但它 returns 更奇怪的结果:

"Optional([32, 16, 38, 24, 30, 29, 0])" 

你最后的结果并不奇怪。可选项来自 string?cString() 函数 returns CChar ( Int8 ) 数组。

我认为问题出在这里 - 但我不确定,因为整个事情看起来很混乱:

[sb appendString:[NSString stringWithFormat:@"%c",c]];

你试过了吗:

[sb appendString: [NSString stringWithCString:c encoding:NSUTF8StringEncoding]];

而不是 stringWithFormat?

(您的评论者提出的 %C 而不是 %c 的解决方案看起来也是个好主意。) - 糟糕 - 刚刚看到您已经尝试过但没有成功。

分析。抱歉,我不会说 swiftObjective-C 所以下面的例子在 Python ;然而,第 4 和第 5 列(unicode 减少到 8 位)回忆起你问题中的 weird 数字。

for ch in 'РАЦИОН':
   print(ch,                          # character itself
      ord(ch),                        # character unicode in decimal
      '{:04x}'.format(ord(ch)),       # character unicode in hexadecimal
      (ord(ch)&0xFF),                 # unicode reduced to 8-bit decimal
      '{:02x}'.format(ord(ch)&0xFF))  # unicode reduced to 8-bit hexadecimal
Р 1056 0420 32 20
А 1040 0410 16 10
Ц 1062 0426 38 26
И 1048 0418 24 18
О 1054 041e 30 1e
Н 1053 041d 29 1d

解决方案。因此,您需要修复所有代码 reducing 16 位到 8 位:
首先,在第 4 行声明 unichar c; 而不是 char c;
并在第 11 行使用 [sb appendString:[NSString stringWithFormat:@"%C",c]];线;注意

  • %C 说明符中的拉丁文大写字母 C 16 位 UTF-16 代码单元 (unichar) 而不是
  • Latin Small Letter C in %c 说明符 8 位无符号字符(unsigned char) ;

资源。我的回答基于以下问题的答案: