BadCats
@BadCats

Удалить Emojii символ из строки в Qt?

Есть эмодзи https://emojipedia.org/tooth/ - необхлдимо удалить его из строки.

Юникод брал отсюда: https://www.fileformat.info/info/unicode/char/1f9b...

Варианты:

C/C++/Java source code "\uD83E\uDDB7"


if (d->at(k).contains(u8"\\uD83E\\uDDB7")) 

if (d->at(k).contains(QString::fromUtf8(QByteArray("f09fa6b7"))))

Оба варианта не срабатывают.

Небольшое уточнение:

В Qt данный эмодзи отображается как два символа 55358(0xd83e) и 56759 (0xdbd7), как и здесь:

www.mauvecloud.net/charsets/CharCodeFinder.html
(для проверки - скопировать отсюда - https://emojipedia.org/tooth/)

причем, проверки на эти два символа:

if (d->at(k).contains("0xd83e")) и if (d->at(k).contains("0xdbd7"))
- как раз, наоборот срабатывают, но

const_cast<QString*>(&d->at(k))->remove("\0xd83e");
const_cast<QString*>(&d->at(k))->remove("\0xdbd7");

- не дают эффекта.

Основной вопрос:

Прошу подсказать, как удалить данный символ и ему подомные(эмодзи)

Дополнительный вопрос:
Так же, что можно почитать про вопросы связанные с кодировкой и ее форматами.
  • Вопрос задан
  • 269 просмотров
Решения вопроса 1
BadCats
@BadCats Автор вопроса
Получилось удалить символы. Суть в том, что Qt почему-то не воспринимает симол, если пытаться удалить или заменить его, обращаясь, как
U0001F9B7
, даже, если символ там точно присутствует и выводится в таком формате в консоль, через qDebug().

Для удаления симолов эмодзи, необходимо воспользоваться статическим методом QString::fromWCharArray() - куда передать сурогатные пары

(как раз те, ккоторые видны в отладчике как 55358(0xd83e) и 56759 (0xdbd7) - в моем случае, для данного эмодзи).

Метод будет выглядеть так:

QString::fromWCharArray(L"\xD83E\xDDB7");

и, он как это не странно вернет ту же строку - U0001F9B7, но вот ее, почему-то, Qt уже прекрасно удаляет:

QString tmpStr=QString::fromWCharArray(L"\xD83E\xDDB7");
myStr.remove(tmpStr);


В поисках ответа мне помогли:

Эта тема на английском SO:
https://stackoverflow.com/questions/30247319/how-d...
(Не уверен, можно ли на тостере оставлять ссылки на другие форумы, поэтому, вот цитата ответа:


You already know the answer - specify it as a proper UTF-16 string.

Unicode codepoints above U+FFFF are represented in UTF-16 using a surrogate pair, which is two 16bit codeunits acting together to represent the full Unicode codepoint value. For U+1F50E, the surrogate pair is U+D83D U+DD0E.

In Qt, a UTF-16 codeunit is represented as a QChar, so you need two QChar values, eg:

edit.setText(QString::fromWCharArray(L"\xD83D\xDD0E"));


or:

edit.setText(QString::fromStdWString(L"\xD83D\xDD0E"));


Assuming a platform where sizeof(wchar_t) is 2 and not 4.

In your example, you tried using QString::fromUtf8(), but you gave it an invalid UTF-8 string. For U+1F50E, it should have looked like this instead:

edit.setText(QString::fromUtf8("\xF0\x9F\x94\x8E"));


You can also use QString::fromUcs4() instead:

uint cp = 0x1F50E; edit.setText(QString::fromUcs4(&cp, 1));



)
Данный калькулятор для вычисления юникода по суррогатным парам и наоборот:
www.russellcottrell.com/greek/utilities/SurrogateP...
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
IGHOR
@IGHOR Куратор тега Qt
Qt/C++ DEV/CTO
void translateUnicodeStr(QString& str)
{
    static const QRegExp rx("(\\\\u[0-9a-fA-F]{4})");
    int pos = 0;

    while ((pos = rx.indexIn(str, pos)) != -1)
        str.replace(pos++, 6, QChar(rx.cap(1).right(4).toUShort(nullptr, 16)));
}
Ответ написан
Vapaamies
@Vapaamies
Разработчик будущей ОС для ПК размером 250 МБ
return str.remove(QRegularExpression("[\\x{1F600}-\\x{1F7FF}]+"));
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы