[java] Java에서 인쇄 할 수없는 유니 코드 문자를 어떻게 바꿀 수 있습니까?

다음은 ASCII 제어 문자 (의 약어)를 대체합니다 [\x00-\x1F\x7F].

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

다음은 [\p{Graph}\x20]악센트 부호가있는 문자를 포함하여 인쇄 할 수없는 모든 ASCII 문자 (의 약어)를 대체합니다 .

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

그러나 유니 코드 문자열에는 둘 다 작동하지 않습니다. 누구든지 유니 코드 문자열에서 인쇄 할 수없는 문자를 제거하는 좋은 방법이 있습니까?



답변

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

유니 코드 정규식 에 대해 자세히 알아보세요 . 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;
    }
}


답변

당신은에 관심이있을 수 있습니다 유니 코드 범주 “기타, 제어”가능성 “기타, 형식” (불행하게도 후자는 모두 인쇄 할 수없는 및 인쇄 가능한 문자를 포함 할 것).

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


답변

이 간단한 기능을 사용했습니다.

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. 공백을 제외한 모든 “보이지 않는 유니 코드 문자”제거 :

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