Как обнаружить «(Unicode) в строке C ++ - PullRequest
0 голосов
/ 06 июля 2018

Я пытаюсь обнаружить некоторую комбинацию символа Unicode (например,) для очистки строки. Для одного символа Unicode он обнаруживает, но комбинация Unicode не обнаруживает.

Эти строки я использую для создания HTML-страницы из другой HTML-страницы, которую необходимо очистить.Я хочу очистить только строку с таким видом Юникода, который даже не виден на 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. " "

Пожалуйста, дайте мне знать и другие способы.

1 Ответ

0 голосов
/ 06 июля 2018

ОК, следуя вышеприведенным комментариям, я думаю, что весьма вероятно, что входная строка находится в 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.

Живая демоверсия .

Вдохновение взято с здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...