ОК, следуя вышеприведенным комментариям, я думаю, что весьма вероятно, что входная строка находится в 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()
выглядит некорректно. Дело в том, что преобразование входной строки в широкую строку означает, что вы можете надежно использовать стандартные операции basic_string
, поскольку в настоящее время нет многобайтовых проблем.
Альтернативная, немного радикальная реализация detect_Unicode()
может быть:
for (auto wide_char : ws)
{
if (wide_char > 0xff)
return " ";
}
return s;
Но на самом деле, теперь у вас есть широкая строка для detect_Unicode
, все возможно, так что помешайте OP.
Другие примечания:
std::codecvt
устарела в C ++ 17, но, поскольку нет другого очевидного выбора, вы могли бы также использовать его. Вы всегда можете изменить реализации narrow
и widen
, если это произойдет.
- В зависимости от платформы,
std::wstring
может быть не лучшим выбором, но, вероятно, это хорошо. Вы также можете посмотреть на std::u16string
и std::u32string
.
Живая демоверсия .
Вдохновение взято с здесь .