Подтвердить что ты не робот

Удалите ✅, ?, ✈, ♛ и другие подобные смайлики/изображения/знаки из строк Java

У меня есть несколько строк со всеми видами разных эмоций/образов/знаков в них.

Не все строки написаны на английском языке - некоторые из них находятся на других нелатинских языках, например:

▓ railway??
→ Cats and dogs
I'm on 🔥
Apples ⚛ 
✅ Vi sign
♛ I'm the king ♛ 
Corée ♦ du Nord ☁  (French)
 gjør at både ◄╗ (Norwegian)
Star me ★
Star ⭐ once more
早上好 ♛ (Chinese)
Καλημέρα ✂ (Greek)
another ✓ sign ✓
добрай раніцы ✪ (Belarus)
◄ शुभ प्रभात ◄ (Hindi)
✪ ✰ ❈ ❧ Let get together ★. We shall meet at 12/10/2018 10:00 AM at Tony's.❉

... и многое другое.

Я хотел бы избавиться от всех этих знаков/изображений и сохранить только буквы (и знаки препинания) на разных языках.

Я попытался очистить знаки, используя библиотеку EmojiParser:

String withoutEmojis = EmojiParser.removeAllEmojis(input);

Проблема в том, что EmojiParser не может удалить большинство знаков. Знак ♦ - единственный, который я нашел до сих пор, когда он удалился. Другие знаки, такие как ✪ ❉ ★ ✰ ❈ ❧ ✂ ❋ ⓡ ✿ ♛ 🔥, не удаляются.

Есть ли способ удалить все эти знаки из входных строк и сохранить только буквы и знаки препинания на разных языках?

4b9b3361

Ответ 1

Вместо того, чтобы вносить в черный список некоторые элементы, как насчет создания белого списка символов, которые вы хотите сохранить? Таким образом, вам не нужно беспокоиться о том, что каждый новый добавленный имидж.

String characterFilter = "[^\\p{L}\\p{M}\\p{N}\\p{P}\\p{Z}\\p{Cf}\\p{Cs}\\s]";
String emotionless = aString.replaceAll(characterFilter,"");

Так:

  • [\\p{L}\\p{M}\\p{N}\\p{P}\\p{Z}\\p{Cf}\\p{Cs}\\s] - диапазон представляющих все числовые (\\p{N}), письмо (\\p{L}), знак (\\p{M}), пунктуации (\\p{P}), пробельные/разделитель (\\p{Z}), другое форматирование (\\p{Cf}) и другие символы выше U+FFFF в символах Unicode (\\p{Cs}) и newline (\\s). \\p{L} включает в себя символы из других алфавитов, таких как кириллица, латынь, кандзи и т.д.
  • Символ ^ в наборе символов регулярных выражений отрицает совпадение.

Пример:

String str = "hello world _# 皆さん、こんにちは! 私はジョンと申します。🔥";
System.out.print(str.replaceAll("[^\\p{L}\\p{M}\\p{N}\\p{P}\\p{Z}\\p{Cf}\\p{Cs}\\s]",""));
// Output:
//   "hello world _# 皆さん、こんにちは! 私はジョンと申します。"

Если вам нужна дополнительная информация, ознакомьтесь с документацией Java для регулярных выражений.

Ответ 2

Я не супер в Java, поэтому я не буду пытаться писать примерный код inline, но способ, которым я это сделаю, - проверить, что Unicode вызывает "общую категорию" каждого символа. Есть две буквы и знаки препинания.

Вы можете использовать Character.getType, чтобы найти общую категорию данного символа. Вероятно, вы должны сохранить те персонажи, которые попадают в эти общие категории:

COMBINING_SPACING_MARK
CONNECTOR_PUNCTUATION
CURRENCY_SYMBOL
DASH_PUNCTUATION
DECIMAL_DIGIT_NUMBER
ENCLOSING_MARK
END_PUNCTUATION
FINAL_QUOTE_PUNCTUATION
FORMAT
INITIAL_QUOTE_PUNCTUATION
LETTER_NUMBER
LINE_SEPARATOR
LOWERCASE_LETTER
MATH_SYMBOL
MODIFIER_LETTER
MODIFIER_SYMBOL
NON_SPACING_MARK
OTHER_LETTER
OTHER_NUMBER
OTHER_PUNCTUATION
PARAGRAPH_SEPARATOR
SPACE_SEPARATOR
START_PUNCTUATION
TITLECASE_LETTER
UPPERCASE_LETTER

(Все персонажи, которые вы указали как специально предназначенные для удаления, имеют общую категорию OTHER_SYMBOL, которую я не включил в белый список категории.)

Ответ 3

На основе полного списка Emoji, v11.0, вы должны удалить 1644 различных кода кода Unicode. Например, находится в этом списке как U+2705.

Имея полный список emojis, вам нужно отфильтровать их с помощью кодовых точек. Итерация по одиночному char или byte не будет работать, поскольку одна кодовая точка может охватывать несколько байтов. Поскольку Java использует UTF-16, emojis обычно принимает два char.

String input = "ab✅cd";
for (int i = 0; i < input.length();) {
  int cp = input.codePointAt(i);
  // filter out if matches
  i += Character.charCount(cp); 
}

Отображение с кодовой точки Unicode U+2705 на Java int является простым:

int viSign = 0x2705;

или поскольку Java поддерживает строки Unicode:

int viSign = "✅".codePointAt(0);

Ответ 4

ICU4J - ваш друг.

UCharacter.hasBinaryProperty(UProperty.EMOJI);

Не забудьте сохранить обновленную версию icu4j и обратите внимание, что это будет отфильтровывать только официальные символы Unicode, а не символы. Комбинируйте с фильтрацией других типов символов по желанию.

Дополнительная информация: http://icu-project.org/apiref/icu4j/com/ibm/icu/lang/UProperty.html#EMOJI

Ответ 5

Я привел несколько примеров ниже и подумал, что латыни достаточно, но...

Есть ли способ удалить все эти знаки из входной строки и сохранить только буквы и знаки препинания на разных языках?

После редактирования разработал новое решение, используя метод Character.getType, и, как представляется, это лучший снимок.

package zmarcos.emoji;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class TestEmoji {

    public static void main(String[] args) {
        String[] arr = {"Remove ✅, 🔥, ✈ , ♛ and other such signs from Java string",
            "→ Cats and dogs",
            "I'm on 🔥",
            "Apples ⚛ ",
            "✅ Vi sign",
            "♛ I'm the king ♛ ",
            "Star me ★",
            "Star ⭐ once more",
            "早上好 ♛",
            "Καλημέρα ✂"};
        System.out.println("---only letters and spaces alike---\n");
        for (String input : arr) {
            int[] filtered = input.codePoints().filter((cp) -> Character.isLetter(cp) || Character.isWhitespace(cp)).toArray();
            String result = new String(filtered, 0, filtered.length);
            System.out.println(input);
            System.out.println(result);
        }

        System.out.println("\n---unicode blocks white---\n");
        Set<Character.UnicodeBlock> whiteList = new HashSet<>();
        whiteList.add(Character.UnicodeBlock.BASIC_LATIN);
        for (String input : arr) {
            int[] filtered = input.codePoints().filter((cp) -> whiteList.contains(Character.UnicodeBlock.of(cp))).toArray();
            String result = new String(filtered, 0, filtered.length);
            System.out.println(input);
            System.out.println(result);
        }

        System.out.println("\n---unicode blocks black---\n");
        Set<Character.UnicodeBlock> blackList = new HashSet<>();        
        blackList.add(Character.UnicodeBlock.EMOTICONS);
        blackList.add(Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL);
        blackList.add(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS);
        blackList.add(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_ARROWS);
        blackList.add(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS);
        blackList.add(Character.UnicodeBlock.ALCHEMICAL_SYMBOLS);
        blackList.add(Character.UnicodeBlock.TRANSPORT_AND_MAP_SYMBOLS);
        blackList.add(Character.UnicodeBlock.GEOMETRIC_SHAPES);
        blackList.add(Character.UnicodeBlock.DINGBATS);
        for (String input : arr) {
            int[] filtered = input.codePoints().filter((cp) -> !blackList.contains(Character.UnicodeBlock.of(cp))).toArray();
            String result = new String(filtered, 0, filtered.length);
            System.out.println(input);
            System.out.println(result);
        }
        System.out.println("\n---category---\n");
        int[] category = {Character.COMBINING_SPACING_MARK, Character.COMBINING_SPACING_MARK, Character.CONNECTOR_PUNCTUATION, /*Character.CONTROL,*/ Character.CURRENCY_SYMBOL,
            Character.DASH_PUNCTUATION, Character.DECIMAL_DIGIT_NUMBER, Character.ENCLOSING_MARK, Character.END_PUNCTUATION, Character.FINAL_QUOTE_PUNCTUATION,
            /*Character.FORMAT,*/ Character.INITIAL_QUOTE_PUNCTUATION, Character.LETTER_NUMBER, Character.LINE_SEPARATOR, Character.LOWERCASE_LETTER,
            /*Character.MATH_SYMBOL,*/ Character.MODIFIER_LETTER, /*Character.MODIFIER_SYMBOL,*/ Character.NON_SPACING_MARK, Character.OTHER_LETTER, Character.OTHER_NUMBER,
            Character.OTHER_PUNCTUATION, /*Character.OTHER_SYMBOL,*/ Character.PARAGRAPH_SEPARATOR, /*Character.PRIVATE_USE,*/
            Character.SPACE_SEPARATOR, Character.START_PUNCTUATION, /*Character.SURROGATE,*/ Character.TITLECASE_LETTER, /*Character.UNASSIGNED,*/ Character.UPPERCASE_LETTER};
        Arrays.sort(category);
        for (String input : arr) {
            int[] filtered = input.codePoints().filter((cp) -> Arrays.binarySearch(category, Character.getType(cp)) >= 0).toArray();
            String result = new String(filtered, 0, filtered.length);
            System.out.println(input);
            System.out.println(result);
        }
    }

}

Вывод:

---only letters and spaces alike---

Remove ✅, 🔥, ✈ , ♛ and other such signs from Java string
Remove      and other such signs from Java string
→ Cats and dogs
 Cats and dogs
I'm on 🔥
Im on 
Apples ⚛ 
Apples  
✅ Vi sign
 Vi sign
♛ I'm the king ♛ 
 Im the king  
Star me ★
Star me 
Star ⭐ once more
Star  once more
早上好 ♛
早上好 
Καλημέρα ✂
Καλημέρα 

---unicode blocks white---

Remove ✅, 🔥, ✈ , ♛ and other such signs from Java string
Remove , ,  ,  and other such signs from Java string
→ Cats and dogs
 Cats and dogs
I'm on 🔥
I'm on 
Apples ⚛ 
Apples  
✅ Vi sign
 Vi sign
♛ I'm the king ♛ 
 I'm the king  
Star me ★
Star me 
Star ⭐ once more
Star  once more
早上好 ♛

Καλημέρα ✂


---unicode blocks black---

Remove ✅, 🔥, ✈ , ♛ and other such signs from Java string
Remove , ,  ,  and other such signs from Java string
→ Cats and dogs
→ Cats and dogs
I'm on 🔥
I'm on 
Apples ⚛ 
Apples  
✅ Vi sign
 Vi sign
♛ I'm the king ♛ 
 I'm the king  
Star me ★
Star me 
Star ⭐ once more
Star  once more
早上好 ♛
早上好 
Καλημέρα ✂
Καλημέρα 

---category---

Remove ✅, 🔥, ✈ , ♛ and other such signs from Java string
Remove , ,  ,  and other such signs from Java string
→ Cats and dogs
 Cats and dogs
I'm on 🔥
I'm on 
Apples ⚛ 
Apples  
✅ Vi sign
 Vi sign
♛ I'm the king ♛ 
 I'm the king  
Star me ★
Star me 
Star ⭐ once more
Star  once more
早上好 ♛
早上好 
Καλημέρα ✂
Καλημέρα 

Код работает путем потоковой передачи строки в кодовые. Затем, используя lambdas для фильтрации символов в массив int, мы преобразуем массив в String.

Буквы и пробелы используются с использованием методов Character для фильтрации, а не с пунктуацией. Неудачная попытка.

Юникод блокирует белый фильтр, используя блоки юникода, которые программист определяет как разрешенные. Неудачная попытка.

Юникод блокирует черный фильтр, используя блоки юникода, которые программист задает как недопустимый. Неудачная попытка.

Фильтр категории с использованием статического метода Character.getType. Программист может определить в массиве category какие типы разрешены. РАБОТЫ 😨😱😰😲😀.

Ответ 6

Используйте плагин jQuery под названием RM-Emoji. Вот как это работает:

$('#text').remove('emoji').fast()

Это быстрый режим, который может пропустить некоторые эмоции, поскольку он использует эвристические алгоритмы для поиска emojis в тексте. Используйте метод .full() для сканирования всей строки и удаления всех emojis.

Ответ 7

Используя стороннюю библиотеку emoji-java, можно легко выполнить многие операции на emoji

Вы можете легко удалить emojis из строки, используя один из следующих способов:

  1. EmojiParser # removeAllEmojis (String): удаляет все emojis из String.
  2. EmojiParser # removeAllEmojisExcept (String, Collection): удаляет все emojis из String, кроме тех, что находятся в коллекции.
  3. EmojiParser # removeEmojis (String, Collection): удаляет emojis в коллекции из String.

Например

String str = "An 😀awesome 😃string with a few 😉emojis!";
Collection<Emoji> collection = new ArrayList<Emoji>();
collection.add(EmojiManager.getForAlias("wink")); // This is 😉
System.out.println(EmojiParser.removeAllEmojis(str));
System.out.println(EmojiParser.removeAllEmojisExcept(str, collection));
System.out.println(EmojiParser.removeEmojis(str, collection));

Вывод

// Prints:
// "An awesome string with a few emojis!"
// "An awesome string with a few 😉emojis!"
// "An 😀awesome 😃string with a few emojis!"

Как его получить?

Via Maven:

<dependency>
  <groupId>com.vdurmont</groupId>
  <artifactId>emoji-java</artifactId>
  <version>4.0.0</version>
</dependency>

Via Gradle:

compile 'com.vdurmont:emoji-java:4.0.0'

Ответ 8

Попробуйте этот проект simple-emoji-4j

Совместим с Emoji 12.0 (2018.10.15)

Просто с:

EmojiUtils.removeEmoji(str)