我正在尝试检测Unicode字符的某些组合(如​)以清理字符串。对于单个Unicode字符,它正在检测,但是未检测到Unicode组合。
我正在使用这些字符串从另一个需要清除的HTML页面制作HTML页面。我只想清理具有此类unicode的字符串,即使在浏览器的html页面中也不可见。
下面是示例代码:
void detect_Unicode(string& str) {
if(!str.empty() && str.find_first_not_of(" \t\n\r\f\v\u00A0\u00C2\u00E2\u20AC\u2039")==string::npos)
str.assign(" ");
return;
}
输入字符串:
1. " ​ ​ " ;
2. "are   there is something    ​ combination ​"
3. " Â Â "
4. "​   ​"
5 . "Â Â â â"
预期输出:
1. " "
2. "are   there is something    ​ combination ​"
3. " "
4. " "
5. " "
也请让我知道其他方式。
答案 0 :(得分:2)
好的,接着上面的评论,我认为输入字符串很有可能是UTF-8(毕竟,在HTML上下文中,还会是什么?)。
在此基础上,我谦虚地提交:
#include <string>
#include <codecvt>
#include <locale>
std::string narrow (const std::wstring& ws)
{
std::wstring_convert <std::codecvt_utf8 <wchar_t>, wchar_t> convert;
return convert.to_bytes (ws);
}
std::wstring widen (const std::string& s)
{
std::wstring_convert <std::codecvt_utf8 <wchar_t>, wchar_t> convert;
return convert.from_bytes (s);
}
std::string detect_Unicode (const std::string& s)
{
std::wstring ws = widen (s);
if (ws.empty() || ws.find_first_not_of (L" \t\n\r\f\v\u00A0\u00C2\u00E2\u20AC\u2039") != std::wstring::npos)
return " ";
return s;
}
#include <iostream>
int main ()
{
std::cout << narrow (L"\u00A0 \u00C2 \u00E2 \u20AC \u2039\n\n");
std::cout << "0.\t\"" << detect_Unicode (u8"abcde") << "\"\n";
std::cout << "1.\t\"" << detect_Unicode (u8" ​ ​ ") << "\"\n";
std::cout << "2.\t\"" << detect_Unicode (u8"are   there is something    ​ combination ​") << "\"\n";
std::cout << "3.\t\"" << detect_Unicode (u8" Â Â ") << "\"\n";
std::cout << "4.\t\"" << detect_Unicode (u8"​   ​") << "\"\n";
std::cout << "5.\t\"" << detect_Unicode (u8"Â Â â â") << "\"\n";
}
输出:
 ⠀ ‹
0. " "
1. " ​ ​ "
2. " "
3. " Â Â "
4. "​   ​"
5. "Â Â â â"
现在这不是OP期望的输出,但是我认为这仅仅是因为detect_Unicode()
的 logic (与实现相反)看起来有缺陷。这里的要点是,将输入字符串转换为宽字符串意味着您可以可靠地对其执行标准basic_string
操作,因为现在没有多字节问题。
detect_Unicode()
的另一种实现方式可能是:
for (auto wide_char : ws)
{
if (wide_char > 0xff)
return " ";
}
return s;
但是,实际上,您现在可以输入detect_Unicode
的字符串很宽,一切皆有可能,因此请执行疯狂的操作。
其他说明:
std::codecvt
在C ++ 17中已被弃用,但是由于没有其他明显的选择,您最好使用它。您可以随时更改narrow
和widen
的实现。std::wstring
可能不是最佳选择,但这可能很好。您还可以查看std::u16string
和std::u32string
。灵感来自here。