itsource

Java에서 인쇄할 수 없는 Unicode 문자를 대체하려면 어떻게 해야 합니까?

mycopycode 2022. 9. 27. 23:53
반응형

Java에서 인쇄할 수 없는 Unicode 문자를 대체하려면 어떻게 해야 합니까?

ASCII 제어 문자(용어)는 다음과 같이 대체됩니다.[\x00-\x1F\x7F]):

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

인쇄 불가능한 ASCII 문자는 다음과 같이 모두 대체됩니다.[\p{Graph}\x20]악센트 문자 포함:

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

단, 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;
    }
}

목표를 위한 아래 방법

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]", "");
} 

Unicode 카테고리 "Other, Control" "Other, Format"에 관심이 있을 수 있습니다(유감스럽게도 Unicode 카테고리에는 인쇄할 수 없는 문자와 인쇄할 수 있는 문자가 모두 포함되어 있는 것 같습니다).

Java 정규 표현에서는 다음을 사용하여 확인할 수 있습니다.\p{Cc}그리고.\p{Cf}각각 다음과 같다.

이 경우 다음과 같은 간단한 기능을 사용했습니다.

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 Cirkel noackjr의 답변에 따르면 일반적인 문자열 클리닝에서는 다음과 같이 합니다. 1. 선행 또는 후행 공백 트리밍, 2. dos2unix, 3. mac2unix, 4. 공백 이외의 모든 "보이지 않는 유니코드 문자" 삭제:

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 자바 문자열에서 숫자 추출 코드를 재설계했습니다.

 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 );
}

언급URL : https://stackoverflow.com/questions/6198986/how-can-i-replace-non-printable-unicode-characters-in-java

반응형