web-dev-qa-db-ja.com

Java文字列から✅、????、✈、♛などの絵文字/ images/signを削除します。

いろいろな絵文字/画像/記号が入った文字列がいくつかあります。

すべての文字列が英語で書かれているわけではありません - それらのいくつかは他のラテン系以外の言語で書かれています、例えば:

▓ 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.❉

...そしてこれらの多くの。

私はこれらのすべてのサイン/画像を取り除き、異なる言語の文字(と句読点)だけを残したいと思います。

EmojiParserライブラリ :を使ってサインをきれいにしようとしました。

String withoutEmojis = EmojiParser.removeAllEmojis(input);

問題は、EmojiParserがサインの大部分を削除できないことです。 ♦サインは、それが削除されたことを今まで私が見つけた唯一のものです。 ✪✪★✰❈❧❧✂✿✿♛????などの他の標識削除されません。

入力文字列からこれらの記号をすべて取り除き、文字と句読点だけを異なる言語に含める方法はありますか?

188
riorio

一部の要素をブラックリストに登録する代わりに、保持したいキャラクターのホワイトリストを作成してみてはいかがですか?これにより、新しい絵文字が追加されることを心配する必要がなくなります。

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})およびUnicode上のU+FFFF上のその他の文字(\\p{Cs})、および改行(\\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 documentation で正規表現を確認してください。

286
Nick Bull

私はJavaに精通していないので、コード例をインラインで書くことはしませんが、これを行う方法は、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を持っています。これは上記のカテゴリーホワイトリストには含まれていませんでした。)

80
Daniel Wagner

フル絵文字リスト、v11.0に基づいて 削除するUnicodeコードポイントは1644あります。例えばはこのリストに U+2705 としてあります。

絵文字の完全なリストを持っているなら、 code points を使ってそれらを除外する必要があります。単一のコードポイントが複数バイトにまたがることがあるため、単一のcharまたはbyteを繰り返し処理しても機能しません。 JavaはUTF-16を使用するため、絵文字は通常2つの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);
47
Karol Dowbecki

ICU4Jはあなたの友達です。

UCharacter.hasBinaryProperty(UProperty.EMOJI);

Icu4jのあなたのバージョンを最新にしておくことを忘れないでください、そしてこれはシンボルの文字ではなく、公式のUnicode絵文字だけを除外することに注意してください。必要に応じて他の文字タイプを除外することと組み合わせてください。

より多くの情報: http://icu-project.org/apiref/icu4j/com/ibm/icu/lang/UProperty.html#EMOJI

20
Daniel F

以下にいくつか例を挙げて、ラテン語で十分だと思いましたが...

入力文字列からこれらの記号をすべて取り除き、異なる言語の文字と句読点だけを残す方法はありますか?

編集後、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
早上好 ♛
早上好 
Καλημέρα ✂
Καλημέρα 

コードは文字列をコードポイントにストリーミングすることによって機能します。次に、ラムダを使用して文字をint配列にフィルタリングし、その配列をStringに変換します。

文字とスペース は、Characterメソッドを使用してフィルタリングしていますが、句読点には適していません。 失敗した試行

unicodeブロックwhite プログラマが許可するように指定したunicodeブロックを使用してフィルタ処理します。 失敗した試行

unicodeブロックはblack プログラマが許可されていないと指定したunicodeブロックを使用してフィルタ処理します。 失敗した試行

静的メソッドCharacter.getTypeを使用した category フィルタ。プログラマーはcategory配列にどの型が許されるかを定義することができます。 _ works _ ????????????????????.

10

RM-EmojiというjQueryプラグインを使用してください。これがどのように動作するのかです:

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

これは、テキスト内の絵文字を見つけるためにヒューリスティックなアルゴリズムを使用しているため、いくつかの絵文字を見逃す可能性がある高速モードです。文字列全体をスキャンし、保証されているすべての絵文字を削除するには、.full()メソッドを使用します。

このプロジェクトをお試しください simple-emoji-4j

絵文字12.0(2018.10.15)との互換性

シンプルで:

EmojiUtils.removeEmoji(str)
0
liheyuan