使用俄语字符解析字符串时出现问题
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 的解决方案看起来也是个好主意。) - 糟糕 - 刚刚看到您已经尝试过但没有成功。
分析。抱歉,我不会说 swift 或 Objective-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) ;
资源。我的回答基于以下问题的答案:
我正在使用一个旧的 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 的解决方案看起来也是个好主意。) - 糟糕 - 刚刚看到您已经尝试过但没有成功。
分析。抱歉,我不会说 swift 或 Objective-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)
资源。我的回答基于以下问题的答案: