簡體   English   中英

如何替換 Java 中不可打印的 Unicode 字符?

[英]How can I replace non-printable Unicode characters in Java?

以下將替換 ASCII 控制字符( [\x00-\x1F\x7F]的簡寫):

my_string.replaceAll("\\p{Cntrl}", "?");

以下將替換所有 ASCII 不可打印字符( [\p{Graph}\x20]的簡寫),包括重音字符:

my_string.replaceAll("[^\\p{Print}]", "?");

但是,兩者都不適用於 Unicode 字符串。 有沒有人有從 unicode 字符串中刪除不可打印字符的好方法?

my_string.replaceAll("\\p{C}", "?");

查看更多關於Unicode 正則表達式 java.util.regexPattern / String.replaceAll支持它們。

Op De Cirkel 大體上是對的。 他的建議在大多數情況下都有效:

 myString.replaceAll("\\p{C}", "?");

但是如果myString可能包含非 BMP 代碼點,那么它會更復雜。 \p{C}包含\p{Cs}的代理代碼點。 上述替換方法有時會僅替換一半代理對,從而破壞非 BMP 代碼點。 這可能是 Java 錯誤而不是預期行為。

使用其他組成類別是一種選擇:

myString.replaceAll("[\\p{Cc}\\p{Cf}\\p{Co}\\p{Cn}]", "?");

但是,不會刪除不屬於一對的單獨代理字符(每個代理字符都有一個分配的代碼點)。 非正則表達式方法是我知道正確處理\p{C}的唯一方法:

StringBuilder newString = new StringBuilder(myString.length());
for (int offset = 0; offset < myString.length();)
{
    int codePoint = myString.codePointAt(offset);
    offset += Character.charCount(codePoint);

    // Replace invisible control characters and unused code points
    switch (Character.getType(codePoint))
    {
        case Character.CONTROL:     // \p{Cc}
        case Character.FORMAT:      // \p{Cf}
        case Character.PRIVATE_USE: // \p{Co}
        case Character.SURROGATE:   // \p{Cs}
        case Character.UNASSIGNED:  // \p{Cn}
            newString.append('?');
            break;
        default:
            newString.append(Character.toChars(codePoint));
            break;
    }
}

您可能對Unicode 類別 “其他,控制”可能“其他,格式”感興趣(不幸的是,后者似乎同時包含不可打印和可打印字符)。

在 Java 正則表達式中,您可以分別使用\p{Cc}\p{Cf}檢查它們。

以下方法可實現您的目標

public static String removeNonAscii(String str)
{
    return str.replaceAll("[^\\x00-\\x7F]", "");
}

public static String removeNonPrintable(String str) // All Control Char
{
    return str.replaceAll("[\\p{C}]", "");
}

public static String removeSomeControlChar(String str) // Some Control Char
{
    return str.replaceAll("[\\p{Cntrl}\\p{Cc}\\p{Cf}\\p{Co}\\p{Cn}]", "");
}

public static String removeFullControlChar(String str)
{
    return removeNonPrintable(str).replaceAll("[\\r\\n\\t]", "");
} 

我為此使用了這個簡單的 function:

private static Pattern pattern = Pattern.compile("[^ -~]");
private static String cleanTheText(String text) {
    Matcher matcher = pattern.matcher(text);
    if ( matcher.find() ) {
        text = text.replace(matcher.group(0), "");
    }
    return text;
}

希望這是有用的。

根據Op De Cirkelnoackjr的回答,以下是我對一般字符串清理所做的工作:1. 修剪前導或尾隨空格,2. dos2unix,3. mac2unix,4. 刪除除空格之外的所有“不可見的 Unicode 字符”:

myString.trim.replaceAll("\r\n", "\n").replaceAll("\r", "\n").replaceAll("[\\p{Cc}\\p{Cf}\\p{Co}\\p{Cn}&&[^\\s]]", "")

用 Scala REPL 測試。

我建議它刪除下面的不可打印字符而不是替換它

private String removeNonBMPCharacters(final String input) {
    StringBuilder strBuilder = new StringBuilder();
    input.codePoints().forEach((i) -> {
        if (Character.isSupplementaryCodePoint(i)) {
            strBuilder.append("?");
        } else {
            strBuilder.append(Character.toChars(i));
        }
    });
    return strBuilder.toString();
}

支持的多語言

public static String cleanUnprintableChars(String text, boolean multilanguage)
{
    String regex = multilanguage ? "[^\\x00-\\xFF]" : "[^\\x00-\\x7F]";
    // strips off all non-ASCII characters
    text = text.replaceAll(regex, "");

    // erases all the ASCII control characters
    text = text.replaceAll("[\\p{Cntrl}&&[^\r\n\t]]", "");

    // removes non-printable characters from Unicode
    text = text.replaceAll("\\p{C}", "");

    return text.trim();
}

我重新設計了電話號碼的代碼 +9 (987) 124124 從 Java 中的字符串中提取數字

 public static String stripNonDigitsV2( CharSequence input ) {
    if (input == null)
        return null;
    if ( input.length() == 0 )
        return "";

    char[] result = new char[input.length()];
    int cursor = 0;
    CharBuffer buffer = CharBuffer.wrap( input );
    int i=0;
    while ( i< buffer.length()  ) { //buffer.hasRemaining()
        char chr = buffer.get(i);
        if (chr=='u'){
            i=i+5;
            chr=buffer.get(i);
        }

        if ( chr > 39 && chr < 58 )
            result[cursor++] = chr;
        i=i+1;
    }

    return new String( result, 0, cursor );
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM