将Unicode字符串转换为NSString

6

我有一个Unicode字符串,如下:

{\rtf1\ansi\ansicpg1252\cocoartf1265
{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fnil\fcharset0 LucidaGrande;}
{\colortbl;\red255\green255\blue255;}
{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{check\}}{\leveltext\leveltemplateid1\'01\uc0\u10003 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1}}
{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}}
\paperw11900\paperh16840\margl1440\margr1440\vieww22880\viewh16200\viewkind0
\pard\li720\fi-720\pardirnatural
\ls1\ilvl0
\f0\fs24 \cf0 {\listtext    
\f1 \uc0\u10003 
\f0     }One\
{\listtext  
\f1 \uc0\u10003 
\f0     }Two\
}

我这里有一个Unicode数据 \u10003,它等价于 "✓" 字符。我尝试使用 [NSString stringWithCharacters:"\u10003" length:NSUTF16StringEncoding] 进行转换,但出现了编译错误。请告诉我如何将这些Unicode字符转换为 "✓"。

谢谢, Boom


1
你用过谷歌吗?这里有一个答案:将Unicode字符转换为NSString - Nitin Gohel
抱歉,我在谷歌上没有找到任何相关内容。大多数都是四位数字,而这里有五个数字。 - boom
这是RTF。你具体想用它做什么? - Martin R
5个回答

15

我有同样的问题,以下代码解决了我的问题。

对于编码:

NSData *dataenc = [yourtext dataUsingEncoding:NSNonLossyASCIIStringEncoding];
NSString *encodevalue = [[NSString alloc]initWithData:dataenc encoding:NSUTF8StringEncoding];

解码所需

 NSData *data = [yourtext dataUsingEncoding:NSUTF8StringEncoding];
 NSString *decodevalue = [[NSString alloc] initWithData:data encoding:NSNonLossyASCIIStringEncoding];

谢谢


给定整个RTF数据,这将返回nil。仅给定\u10003序列,这将返回两个字符(U+1000后跟一个'3'),而不是一个。 https://dev59.com/J3rZa4cB1Zd3GeqP9PXx#0OMLoYgBc1ULPQZFdfs4 - Peter Hosey
2
我在一个Unicode字符串中遇到了问题,你的解决方案帮助我找到了问题,谢谢。 - Fa.Shapouri

8

我已经使用以下代码将Unicode字符串转换为NSString。这应该能正常工作。

    NSData *unicodedStringData =
    [unicodedString dataUsingEncoding:NSUTF8StringEncoding];
    NSString *emojiStringValue =
    [[NSString alloc] initWithData:unicodedStringData encoding:NSNonLossyASCIIStringEncoding];

在Swift 4中

 let emoji = ""
let unicodedData = emoji.data(using: String.Encoding.utf8, allowLossyConversion: true)
let emojiString = String(data: unicodedData!, encoding: String.Encoding.utf8)

enter image description here


给定整个 RTF 数据,这将返回 nil。仅给定 \u10003 序列,这将返回两个字符(U+1000 后跟一个 '3'),而不是一个。https://gist.github.com/boredzo/8305377 - Peter Hosey
请问您是如何对 RTF 字符串进行编码的?我曾经将包含 iOS 表情符号的 NSString 编码为 Unicode,以便在网络上传输,并在应用程序内显示时获取原始的 NSString。这个技巧对我来说一直很有效。 - Pawan Sharma

7
我假设:
  • 你从文件或其他外部来源读取了这段RTF数据。
  • 你正在自己解析它(而不是使用AppKit内置的RTF解析器)。
  • 你有一个理由自己解析它,并且这个理由不是“等一下,AppKit有内置的吗?”。
  • 在你解析的输入中,你遇到了\u…,需要将其转换为一个字符,以便进行进一步处理和/或包含在输出文本中。
  • 你已经排除了\uc,这是另一件事情(如果我正确理解RTF规范,它指定了在\u…序列之后遵循的非Unicode字节数)。

\u后面跟着十六进制数字。你需要将它们解析为一个数字;该数字就是序列所表示的字符的Unicode代码点数值。然后,你需要创建一个包含该字符的NSString。

如果你正在使用NSScanner解析输入,那么(假设你已经扫描过\u本身),你可以简单地要求扫描器scanHexInt:。传递一个指向unsigned int变量的指针。

如果你没有使用NSScanner,请根据你解析它的方式进行适当的操作。例如,如果你已将RTF数据转换为C字符串并正在自己阅读它,则需要使用strtoul来解析十六进制数字。它将在你指定的任何基数(在本例中为16)中解释该数字,然后将下一个字符的指针放置在你想要的位置。

然后,你的unsigned intunsigned long变量将包含指定字符的Unicode代码点值。在你提问中的示例中,这将是0x10003,即U+10003。

现在,对于大多数字符,你可以简单地将其分配给unichar变量,并从中创建一个NSString。但是,这里行不通:unichar只能达到0xFFFF,而此代码点比这更高(技术上来说,它超出了基本多语言平面)。

幸运的是,*CF*String有一个函数可以帮助你:

unsigned int codePoint = /*…*/;

unichar characters[2];
NSUInteger numCharacters = 0;
if (CFStringGetSurrogatePairForLongCharacter(codePoint, characters)) {
    numCharacters = 2;
} else {
    characters[0] = codePoint;
    numCharacters = 1;
}

你可以使用stringWithCharacters:length:方法,从这个包含16位字符的数组中创建一个NSString。

5

使用这个:

NSString *myUnicodeString = @"\u10003"; 

感谢现代的Objective C技术。
如果这不是你想要的,请让我知道。

它不是1003,而是10003。 - boom
那行不通。\u需要一个四位数。你需要使用\U,它需要一个八位数。(当然,你需要用零填充。)此外,这个问题对我来说听起来像是处理输入,而不是(希望不是)在源代码中嵌入固定的RTF字符串。 - Peter Hosey

0
NSString *strUnicodeString = "\u2714";  
NSData *unicodedStringData = [strUnicodeString dataUsingEncoding:NSUTF8StringEncoding];
NSString *emojiStringValue = [[NSString alloc] initWithData:unicodedStringData encoding:NSUTF8StringEncoding];

@zohar,这段代码仅将8位Unicode字符转换为字符串值。在这里我使用了 '\u2714' Unicode 表示勾号,简单地将该Unicode转换为字符串值以表示实际的勾号符号在我的代码中。 - Paras Gupta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接