从字符串中删除特定 Unicode 范围的字符

2022-09-02 22:54:05

我有一个程序,可以从twitter流api实时解析推文。在存储它们之前,我将它们编码为utf8。某些字符最终在字符串中显示为?, ??,或???而不是它们各自的Unicode代码并导致问题。经过进一步调查,我发现有问题的字符来自“表情符号”块U + 1F600 - U + 1F64F和“杂项符号和象形文字”块U + 1F300 - U + 1F5FF。我尝试删除,但没有成功,因为匹配器最终替换了字符串中的几乎每个字符,而不仅仅是我想要的unicode范围。

String utf8tweet = "";
        try {
            byte[] utf8Bytes = status.getText().getBytes("UTF-8");

            utf8tweet = new String(utf8Bytes, "UTF-8");

        } 
        catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
Pattern unicodeOutliers = Pattern.compile("[\\u1f300-\\u1f64f]", Pattern.UNICODE_CASE | Pattern.CANON_EQ | Pattern.CASE_INSENSITIVE);
Matcher unicodeOutlierMatcher = unicodeOutliers.matcher(utf8tweet);
utf8tweet = unicodeOutlierMatcher.replaceAll(" ");

如何删除这些字符?


答案 1

在正则表达式模式中添加否定运算符 。要过滤可打印字符,您可以使用以下表达式,您应该获得所需的结果。^[^\\x00-\\x7F]

import java.io.UnsupportedEncodingException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UTF8 {
    public static void main(String[] args) {
        String utf8tweet = "";
        try {
            byte[] utf8Bytes = "#Hello twitter  How are you?".getBytes("UTF-8");

            utf8tweet = new String(utf8Bytes, "UTF-8");

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        Pattern unicodeOutliers = Pattern.compile("[^\\x00-\\x7F]",
                Pattern.UNICODE_CASE | Pattern.CANON_EQ
                        | Pattern.CASE_INSENSITIVE);
        Matcher unicodeOutlierMatcher = unicodeOutliers.matcher(utf8tweet);

        System.out.println("Before: " + utf8tweet);
        utf8tweet = unicodeOutlierMatcher.replaceAll(" ");
        System.out.println("After: " + utf8tweet);
    }
}

结果为以下输出:

Before: #Hello twitter  How are you?
After: #Hello twitter   How are you?

编辑

为了进一步解释,您还可以继续使用以下形式表示范围,这将匹配所有不是前128个UNICODE字符的字符(与以前相同)。如果要扩展范围以支持额外的字符,可以使用此处的 UNICODE 字符列表执行此操作。\u[^\\u0000-\\u007F]

例如,如果要包含带重音的元音(在西班牙语中使用),则应将范围扩展到 ,以便您拥有 或 :\u00FF[^\\u0000-\\u00FF][^\\x00-\\xFF]

Before: #Hello twitter  How are you? á é í ó ú
After: #Hello twitter   How are you? á é í ó ú

答案 2

首先,相关的unicode块在java中指定(严格遵循标准)为Charact.UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS。在正则表达式中:

s = s.replaceAll("\\p{So}+", "");