我正在用C编写HTML解析器,我希望正确地关注the W3C guidelines on parser implementation。其中一个关键点是解析器是在Unicode代码点流而不是字节上运行的,这是有道理的。
基本上,给定一个已知字符编码的缓冲区<(我会给出一个显式的输入编码,或者使用HTML5预扫描算法做出很好的猜测),最好的方法是什么在C - 理想的跨平台,但坚持UNIX很好 - 迭代一个等效的Unicode代码点序列?
分配一些合理大小的缓冲区并使用iconv
的方式去吗?我应该看ICU吗?像U16_NEXT
这样的宏似乎非常适合我的任务,但是ICU文档非常冗长,而且很难确切地知道如何将各种东西粘在一起。
答案 0 :(得分:2)
ICU是一个不错的选择。我在C ++中使用它并且非常喜欢它。我很确定你在C中也会得到类似的思考API。
不完全相同但有些相关可能是这个tutorial解释了如何执行流式/增量音译(在这种情况下的困难是“光标”可能内部 a有时代码点。
答案 1 :(得分:2)
以下内容将解码一个代码点并返回增加字符串的数量(“咀嚼”多少)。请注意,xs_utf16是unsigned short。更多信息:http://sree.kotay.com/2006/12/unicode-is-pain-in.html
enum
{
xs_UTF_Max = 0x0010FFFFUL,
xs_UTF_Replace = 0x0000FFFDUL,
xs_UTF16_HalfBase = 0x00010000UL,
xs_UTF16_HighStart = 0x0000D800UL,
xs_UTF16_HighEnd = 0x0000DBFFUL,
xs_UTF16_LowStart = 0x0000DC00UL,
xs_UTF16_LowEnd = 0x0000DFFFUL,
xs_UTF16_MaxUCS2 = 0x0000FFFFUL,
xs_UTF16_HalfMask = 0x000003FFUL,
xs_UTF16_HalfShift = 10
};
int32 xs_UTF16Decode (uint32 &code, const xs_utf16* str, int32 len, bool strict)
{
if (str==0||len==0) {code=0; return 0;}
uint32 c1 = str[0];
//note: many implementations test from HighStart to HighEnd,
// this may be a partial code point, and is incorrect(?)
// trivial checking should exclude the WHOLE surrogate range
if (c1<xs_UTF16_HighStart || c1>xs_UTF16_LowEnd) return 1;
//really an error if we're starting in the low range
//surrogate pair
if (len<=1 || str[1]==0) {code=xs_UTF_Replace; return strict ? 0 : 1;} //error
uint32 c2 = str[1];
code = ((c1-xs_UTF16_HighStart)<<xs_UTF16_HalfShift) + (c2-xs_UTF16_LowStart) + xs_UTF16_HalfBase;
if (strict==false) return 2;
//check for errors
if (c1>=xs_UTF16_LowStart && c1<=xs_UTF16_LowEnd) {code=xs_UTF_Replace; return 0;} //error
if (c2<xs_UTF16_LowStart || c2>xs_UTF16_LowEnd) {code=xs_UTF_Replace; return 0;} //error
if (code>xs_UTF_Max) {code=xs_UTF_Replace; return 0;} //error
//success
return 2;
}
答案 2 :(得分:0)
您可能会对以下两件事感兴趣: