替换字符串C++中无效的XML unicode序列

Replace invalid XML unicode sequence in a string C++

本文关键字:XML unicode 序列 无效 字符串 C++ 替换      更新时间:2023-10-16

在C++中查找与Java中的Character.isIdentifierIgnorable()对应的函数。基本上,我必须用从它们派生的另一个字符串来替换它们(这样信息就不会丢失)。

我在Java中的实现:

public static String replaceInvalidChar (String s) {
StringBuffer sb = new StringBuffer();
char[] characters = s.toCharArray();
for (char c : characters) {
if (Character.isIdentifierIgnorable(c)){
sb.append(String.format("\u%04x", (int)c));
} else {
sb.append(c);
}
}
return sb.toString();
}

目的是在C++中也这样做,但为了替换字符,我需要首先检测它们。有人能帮我吗?

根据我所能收集到的关于Character.isIdentifierIgnorable()如何工作的信息,以下内容可能对您有用:

std::wstring replaceInvalidChar(std::wstring const& s)
{
std::wostringstream sb;
for(auto c: s)
{
if(std::iswcntrl(c) && !std::iswspace(c))
sb << L"\u" << std::hex << std::setw(4) << std::setfill(L'0') << int(c);
else
sb << wchar_t(c);
}
return sb.str();
}

根据Java的Character.isIdentifierIgnorable(char)文档:

确定指定字符在Java标识符还是Unicode标识符中应被视为可忽略字符。

以下Unicode字符在Java标识符或Unicode标识符中是可以忽略的:

  • 不是空白的ISO控制字符

    • '\u0000'到'\u0008'
    • '\u000E'到'\u001B'
    • '\u007F'到'\u009F'
  • 具有FORMAT常规类别值的所有字符

注意:此方法无法处理补充字符。要支持所有Unicode字符,包括补充字符,请使用isIdentifierIgnorable(int)方法

参数
ch-要测试的角色。

如果字符是可忽略的控制字符,并且可能是Java或Unicode标识符的一部分,则返回
true;否则为CCD_ 6。

所以,试试这样的东西:

#include <string>
#include <sstream>
#include <iomanip>
bool isFormatChar(wchar_t ch)
{
switch (ch)
{
case 0x00AD:
case 0x2028:
case 0x2029:
case 0x061C:
case 0x200E:
case 0x200F:
case 0x202A:
case 0x202B:
case 0x202C:
case 0x202D:
case 0x202E:
case 0x2066:
case 0x2067:
case 0x2068:
case 0x2069:
// and many many more! For the full list of Format chars, see:
// http://www.fileformat.info/info/unicode/category/Cf/list.htm
// http://www.fileformat.info/info/unicode/category/Zl/list.htm
// http://www.fileformat.info/info/unicode/category/Zp/list.htm
return true;
}
return false;
}
std::wstring replaceInvalidChar(const std::wstring &s)
{
std::wostringstream sb;
for (auto ch: s)
{
if (((ch >= 0x0000) && (ch <= 0x0008)) ||
((ch >= 0x000E) && (ch <= 0x001B)) ||
((ch >= 0x007F) && (ch <= 0x009F)) ||
isFormatChar(ch))
{
sb << L"\u" << std::hex << std::nouppercase << std::setw(4) << std::setfill(L'0') << int(ch);
} 
else
{
sb.put(ch);
}
}
return sb.str();
}