从 Java 字符串中删除 ✅, , ✈ , ♛ 和其他类似的 emojis/images/signs
Remove ✅, , ✈ , ♛ and other such emojis/images/signs from Java strings
我有一些字符串,其中包含各种不同的 emojis/images/signs。
并非所有字符串都是英文的——其中一些字符串是其他非拉丁语,例如:
▓ 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.❉
...还有更多这些。
我想摆脱所有这些 signs/images 并只保留不同语言的字母(和标点符号)。
我尝试使用 EmojiParser library:
清洁标牌
String withoutEmojis = EmojiParser.removeAllEmojis(input);
问题是 EmojiParser 无法删除大部分符号。 ♦ 标志是迄今为止我发现的唯一一个被删除的标志。
其他符号如✪❉★✰❈❧✂❋ⓡ✿♛不去掉
有没有办法从输入字符串中删除所有这些符号,只保留不同语言中的字母和标点符号?
基于Full Emoji List, v11.0 you have 1644 different Unicode code points to remove. For example ✅
is on this list as U+2705
。
拥有完整的表情符号列表后,您需要使用 code points 将它们过滤掉。迭代单个 char
或 byte
将不起作用,因为单个代码点可以跨越多个字节。因为 Java 使用 UTF-16 表情符号通常需要两个 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);
与其将某些元素列入黑名单,不如创建一个您希望保留的字符的白名单怎么样?这样您就不必担心每个新的表情符号都会被添加。
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}
)的范围、whitespace/separator (\p{Z}
)、其他格式 (\p{Cf}
) 和 Unicode 中 U+FFFF
以上的其他字符 (\p{Cs}
) 和换行符 (\s
) 人物。 \p{L}
特别地 包括来自其他字母表的字符,例如西里尔字母、拉丁字母、汉字等。
- regex 字符集中的
^
否定匹配。
示例:
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 的正则表达式。
我不是很喜欢 Java,所以我不会尝试编写内联示例代码,但我这样做的方法是检查 Unicode 对每个字符的调用 "the general category" .有几个字母和标点符号类别。
您可以使用 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
,我没有将其包含在上述类别白名单中。)
我在下面举了一些例子,认为拉丁语就足够了,但是...
Is there a way to remove all these signs from the input string and
keeping only the letters & punctuation in the different languages?
编辑后,开发了一个新的解决方案,使用 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
早上好 ♛
早上好
Καλημέρα ✂
Καλημέρα
代码通过将字符串流式传输到 code-points 来工作。然后使用 lambdas 将字符过滤成 int
数组,然后我们将数组转换为 String.
字母和空格是用Character的方法过滤的,不好用标点符号。 尝试失败。
unicode blocks white 过滤器使用程序员指定为允许的 unicode 块。 尝试失败。
unicode blocks black 过滤器使用程序员指定为不允许的 unicode 块。 尝试失败。
类别过滤器使用静态方法Character.getType
。程序员可以在 category
数组中定义允许的类型。 作品.
ICU4J 是你的朋友。
UCharacter.hasBinaryProperty(UProperty.EMOJI);
记得保持你的 icu4j 版本是最新的,注意这只会过滤掉官方的 Unicode 表情符号,而不是符号字符。根据需要结合过滤掉其他字符类型。
更多信息:
http://icu-project.org/apiref/icu4j/com/ibm/icu/lang/UProperty.html#EMOJI
使用名为 RM-Emoji 的 jQuery 插件。它是这样工作的:
$('#text').remove('emoji').fast()
这是快速模式,可能会遗漏一些表情符号,因为它使用启发式算法在文本中查找表情符号。使用 .full()
方法扫描整个字符串并删除所有保证的表情符号。
试试这个项目simple-emoji-4j
兼容 Emoji 12.0 (2018.10.15)
简单:
EmojiUtils.removeEmoji(str)
我有一些字符串,其中包含各种不同的 emojis/images/signs。
并非所有字符串都是英文的——其中一些字符串是其他非拉丁语,例如:
▓ 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.❉
...还有更多这些。
我想摆脱所有这些 signs/images 并只保留不同语言的字母(和标点符号)。
我尝试使用 EmojiParser library:
清洁标牌String withoutEmojis = EmojiParser.removeAllEmojis(input);
问题是 EmojiParser 无法删除大部分符号。 ♦ 标志是迄今为止我发现的唯一一个被删除的标志。 其他符号如✪❉★✰❈❧✂❋ⓡ✿♛不去掉
有没有办法从输入字符串中删除所有这些符号,只保留不同语言中的字母和标点符号?
基于Full Emoji List, v11.0 you have 1644 different Unicode code points to remove. For example ✅
is on this list as U+2705
。
拥有完整的表情符号列表后,您需要使用 code points 将它们过滤掉。迭代单个 char
或 byte
将不起作用,因为单个代码点可以跨越多个字节。因为 Java 使用 UTF-16 表情符号通常需要两个 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);
与其将某些元素列入黑名单,不如创建一个您希望保留的字符的白名单怎么样?这样您就不必担心每个新的表情符号都会被添加。
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}
)的范围、whitespace/separator (\p{Z}
)、其他格式 (\p{Cf}
) 和 Unicode 中U+FFFF
以上的其他字符 (\p{Cs}
) 和换行符 (\s
) 人物。\p{L}
特别地 包括来自其他字母表的字符,例如西里尔字母、拉丁字母、汉字等。- regex 字符集中的
^
否定匹配。
示例:
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 的正则表达式。
我不是很喜欢 Java,所以我不会尝试编写内联示例代码,但我这样做的方法是检查 Unicode 对每个字符的调用 "the general category" .有几个字母和标点符号类别。
您可以使用 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
,我没有将其包含在上述类别白名单中。)
我在下面举了一些例子,认为拉丁语就足够了,但是...
Is there a way to remove all these signs from the input string and keeping only the letters & punctuation in the different languages?
编辑后,开发了一个新的解决方案,使用 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
早上好 ♛
早上好
Καλημέρα ✂
Καλημέρα
代码通过将字符串流式传输到 code-points 来工作。然后使用 lambdas 将字符过滤成 int
数组,然后我们将数组转换为 String.
字母和空格是用Character的方法过滤的,不好用标点符号。 尝试失败。
unicode blocks white 过滤器使用程序员指定为允许的 unicode 块。 尝试失败。
unicode blocks black 过滤器使用程序员指定为不允许的 unicode 块。 尝试失败。
类别过滤器使用静态方法Character.getType
。程序员可以在 category
数组中定义允许的类型。 作品.
ICU4J 是你的朋友。
UCharacter.hasBinaryProperty(UProperty.EMOJI);
记得保持你的 icu4j 版本是最新的,注意这只会过滤掉官方的 Unicode 表情符号,而不是符号字符。根据需要结合过滤掉其他字符类型。
更多信息: http://icu-project.org/apiref/icu4j/com/ibm/icu/lang/UProperty.html#EMOJI
使用名为 RM-Emoji 的 jQuery 插件。它是这样工作的:
$('#text').remove('emoji').fast()
这是快速模式,可能会遗漏一些表情符号,因为它使用启发式算法在文本中查找表情符号。使用 .full()
方法扫描整个字符串并删除所有保证的表情符号。
试试这个项目simple-emoji-4j
兼容 Emoji 12.0 (2018.10.15)
简单:
EmojiUtils.removeEmoji(str)