Jak mogę zastąpić niedrukowalne znaki Unicode w Javie?

Następujące znaki kontrolne ASCII (skrót od [\x00-\x1F\x7F]):

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

Poniższy tekst zastąpi wszystkie znaki niedrukowalne ASCII( Skrót [\p{Graph}\x20]), w tym znaki akcentowane:

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

Jednak żaden z nich nie działa dla ciągów Unicode. Czy ktoś ma dobry sposób na usunięcie niedrukowalnych znaków z ciągu unicode?

Author: David Foerster, 2011-06-01

6 answers

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

Zobacz więcej o regex Unicode. java.util.regexPattern/String.replaceAll wspiera ich.

 105
Author: Op De Cirkel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-15 00:10:37

Op de Cirkel ma w większości rację. Jego sugestia zadziała w większości przypadków:

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

Ale jeśli myString może zawierać Punkty kodowe inne niż BMP, to jest to bardziej skomplikowane. \p{C} zawiera zastępcze Punkty kodowe \p{Cs}. Powyższa metoda wymiany spowoduje uszkodzenie punktów kodowych innych niż BMP, czasami zastępując tylko połowę pary zastępczej. Możliwe, że jest to błąd Javy, a nie zamierzone zachowanie.

Użycie innych kategorii składowych jest opcja:

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

Jednak pojedyncze znaki zastępcze nie będące częścią pary (każdy znak zastępczy ma przypisany punkt kodowy) nie zostaną usunięte. Metoda non-regex jest jedynym sposobem, który znam, aby poprawnie obsłużyć \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;
    }
}
 44
Author: noackjr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-03 23:24:43

Być może zainteresują Cię kategorie Unicode "Inne, Control"i ewentualnie "Inne, Format" (niestety ten ostatni wydaje się zawierać zarówno znaki niedrukowalne, jak i drukowalne).

W wyrażeniach regularnych Javy można je sprawdzić, używając odpowiednio \p{Cc} i \p{Cf}.

 6
Author: Joachim Sauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-01 10:48:48

Metody w blow for your goal

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]", "");
} 
 1
Author: Ali Bagheri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-05 07:42:15

Użyłem do tego prostej funkcji:

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;
}
Mam nadzieję, że to się przyda.
 0
Author: user1300830,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-27 11:13:58

Przeprojektowałem kod dla numerów telefonów + 9 (987) 124124 Wyodrębnij cyfry z ciągu znaków w Javie

 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 );
}
 -3
Author: Kairat Koibagarov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:07