Mam kilka ciągów znaków z różnymi rodzajami emoji / obrazów / znaków.
Nie wszystkie ciągi są w języku angielskim - niektóre z nich są w innych językach niełacińskich, na przykład:
▓ 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's get together ★. We shall meet at 12/10/2018 10:00 AM at Tony's.❉
... i wiele innych.
Chciałbym pozbyć się wszystkich tych znaków / obrazów i zachować tylko litery (i znaki interpunkcyjne) w różnych językach.
Próbowałem wyczyścić znaki przy użyciu biblioteki EmojiParser :
String withoutEmojis = EmojiParser.removeAllEmojis(input);
Problem polega na tym, że EmojiParser nie jest w stanie usunąć większości znaków. Znak ♦ jest jedynym, jaki do tej pory znalazłem, kiedy go usunąłem. Inne znaki, takie jak ✪ ❉ ★ ✰ ❈ ❧ ✂ ❋ ⓡ ✿ ♛ 🔥, nie są usuwane.
Czy istnieje sposób na usunięcie wszystkich tych znaków z ciągów wejściowych i zachowanie tylko liter i interpunkcji w różnych językach ?
Odpowiedzi:
Zamiast umieszczać na czarnej liście niektóre elementy, co powiesz na utworzenie białej listy znaków, które chcesz zachować? W ten sposób nie musisz się martwić dodawaniem nowych emoji.
Więc:
[\\p{L}\\p{M}\\p{N}\\p{P}\\p{Z}\\p{Cf}\\p{Cs}\\s]
to zakres reprezentujący wszystkie cyfry (\\p{N}
), literę (\\p{L}
), znak (\\p{M}
), interpunkcję (\\p{P}
), białe znaki / separator (\\p{Z}
), inne formatowanie (\\p{Cf}
) i inne powyższe znakiU+FFFF
w Unicode (\\p{Cs}
) i\\s
znak nowej linii ( ).\\p{L}
w szczególności obejmuje znaki z innych alfabetów, takich jak cyrylica, łacina, kanji itp.^
znaków wyrażenia regularnego neguje dopasowanie.Przykład:
Jeśli potrzebujesz więcej informacji, zapoznaj się z dokumentacją Java dla wyrażeń regularnych.
źródło
[^\w\^\-\[\]\.!@#$%&*\(\)/+'":;~?,]
ale to po prostu jestem silny i próbuję zebrać wszystkie typowe znaki, które nie są symbole t). Pozytywnie oceniany, ponieważ jest to z pewnością potencjalne rozwiązanie. Jeśli chce dodać inne znaki języka, może w razie potrzeby dodać je do wyrażenia.p{L}
obsługuje nieangielskie znaki alfabetyczne . Mam nadzieję, że zrozumiałe jest, że nie potrafię wyczerpująco wypisać wszystkich alfabetów nieanglojęzycznych w mojej odpowiedzi, ponieważ byłoby to niepraktycznie gadatliwe."[^\\p{L}\\p{M}\\p{N}\\p{P}\\p{Z}\\p{Cf}\\s]"
. Pozwala to na kategorie ogólne Litera, Znak, Liczba, Interpunkcja, Separator i „Inne, Format”, a także znaki spacji, takie jak tabulator i znak nowej linii.Nie przepadam za Javą, więc nie będę próbował pisać przykładowego kodu inline, ale sposób, w jaki to zrobię, to sprawdzenie, co Unicode nazywa „kategorią ogólną” każdego znaku. Istnieje kilka liter i kategorii interpunkcyjnych.
Możesz użyć Character.getType, aby znaleźć ogólną kategorię danego znaku. Prawdopodobnie powinieneś zachować te postacie, które należą do tych ogólnych kategorii:
(Wszystkie postacie, które chciałeś usunąć, mają kategorię ogólną
OTHER_SYMBOL
, której nie znalazłem na białej liście powyższych kategorii).źródło
Character.getType()
nie powie ci, czy twójchar
(lubint
punkt kodowy od momentu przeciążenia metody) jest, powiedzmy, emotikonem, symbolem muzycznym, znakiem emoji itp. Jeśli masz prosty przypadek użycia, może być w porządku pójść tą ścieżką - to z pewnością eleganckie i łatwe do zrozumienia podejście - ale pamiętaj, że może się złamać, jeśli zmienią się wymagania.W oparciu o pełną listę emotikonów wer. 11.0 masz 1644 różnych punktów kodu Unicode do usunięcia. Na przykład
✅
jest na tej liście jakoU+2705
.Mając pełną listę emotikonów, musisz je odfiltrować za pomocą punktów kodowych . Iteracja po pojedynczym
char
lubbyte
nie będzie działać, ponieważ pojedynczy punkt kodowy może obejmować wiele bajtów. Ponieważ Java używa emoji UTF-16 zwykle zajmuje dwachar
s.Mapowanie z punktu kodu Unicode
U+2705
na Javęint
jest proste:lub ponieważ Java obsługuje ciągi Unicode:
źródło
input.codePointAt
patrzy tylko na maksymalnie 2 znaki, co stanowi stałą górną granicę. Ponadto (nowo dodane)i += Character.charCount(cp)
pomija wszystkie postacie, któreinput.codePointAt
sprawdzono (minus 1 w niektórych przypadkach narożnych).String.chars()
przesyła strumieniowo znaki, a nie znaki kodowe. Jest na to osobna metodaString.codePoints()
.ICU4J jest twoim przyjacielem.
Pamiętaj, aby aktualizować swoją wersję icu4j i pamiętaj, że odfiltruje ona tylko oficjalne emoji Unicode, a nie znaki symboli. Połącz z filtrowaniem innych typów znaków według potrzeb.
Więcej informacji: http://icu-project.org/apiref/icu4j/com/ibm/icu/lang/UProperty.html#EMOJI
źródło
Podałem kilka przykładów poniżej i pomyślałem, że łacina wystarczy, ale ...
Po edycji opracowałem nowe rozwiązanie, korzystając z
Character.getType
metody, i wydaje się, że jest to najlepsze ujęcie.Wynik:
Kod działa poprzez przesyłanie strumienia do punktów kodowych. Następnie za pomocą lambda do filtrowania znaków w
int
tablicy, a następnie przekonwertujemy tablicę na String.Te litery i spacje korzysta z wykorzystaniem metod znak do filtra, nie jest dobra ze znaków interpunkcyjnych. Nieudana próba .
Te bloki Unicode białe filtry wykorzystujące bloków Unicode określa się jako programista dozwolone. Nieudana próba .
Bloków Unicode czarny filtr używając bloków Unicode określa się jako programista nie dozwolony. Nieudana próba .
Kategoria filtr stosując metodę statyczną
Character.getType
. Programista może określić wcategory
tablicy, jakie typy są dozwolone. PRACE 😨😱😰😲😀.źródło
import java.lang.Character.UnicodeBlock;
, a następnieCharacter.UnicodeBlock
->UnicodeBlock
.white list
przykład.Wypróbuj ten projekt simple-emoji-4j
Kompatybilny z Emoji 12.0 (2018.10.15)
Prosty z:
źródło
Użyj wtyczki jQuery o nazwie RM-Emoji. Oto jak to działa:
Jest to tryb szybki, w którym niektóre emoji mogą nie być dostępne, ponieważ wykorzystuje algorytmy heurystyczne do wyszukiwania emoji w tekście. Użyj
.full()
metody, aby zeskanować cały ciąg i usunąć wszystkie emoji gwarantowane.źródło