web-dev-qa-db-ja.com

文字列から非ASCIIの印刷不可能な文字を削除する

次のような非ASCII文字や印刷できない文字を含むユーザー入力を取得します

\xc2d
\xa0
\xe7
\xc3\ufffdd
\xc3\ufffdd
\xc2\xa0
\xc3\xa7
\xa0\xa0

例えば:

email : [email protected]\xa0\xa0
street : 123 Main St.\xc2\xa0

望ましい出力:

  email : [email protected]
  street : 123 Main St.

Javaを使用してそれらを削除する最良の方法は何ですか?
以下を試しましたが、動作しないようです

public static void main(String args[]) throws UnsupportedEncodingException {
        String s = "abc@gmail\\xe9.com";
        String email = "[email protected]\\xa0\\xa0";

        System.out.println(s.replaceAll("\\P{Print}", ""));
        System.out.println(email.replaceAll("\\P{Print}", ""));
    }

出力

abc@gmail\xe9.com
[email protected]\xa0\xa0
16
daydreamer

要件が明確ではありません。 Java String内のすべての文字はUnicode文字であるため、それらを削除すると、空の文字列が残ります。つまり、 ASCII以外の、印刷できない文字を削除します。

String clean = str.replaceAll("\\P{Print}", "");

ここで、\p{Print}POSIX文字クラスを表す は、印刷可能なASCII文字)であり、\P{Print}は、そのクラスの補数です。この式では、 でないすべての文字印刷可能ASCIIは、空の文字列に置き換えられます。(\は、文字列リテラルでエスケープシーケンスを開始します。)


どうやら、すべての入力文字は実際にはASCII印刷不可能な文字または非ASCII文字の印刷可能なエンコーディングを表す文字です。Mongoはこれらの文字列を問題なく扱う必要があります。印刷可能ASCII文字。

これはすべて私には少し怪しげに聞こえます。私が起こっていると私が信じているのは、データには実際に印刷不可および非ASCII文字が含まれており、別のコンポーネント(ロギングフレームワークなど)がこれらを印刷可能な表現に置き換えていることです。単純なテストでは、印刷可能な表現を元の文字列に変換することに失敗しているため、最初の正規表現が機能していないと誤って信じています。

それは私の推測ですが、状況を誤解していて、本当にリテラル\xHHエスケープを取り除く必要がある場合は、次の正規表現を使用してそれを行うことができます。

String clean = str.replaceAll("\\\\x\\p{XDigit}{2}", "");

Pattern クラスのAPIドキュメントは、Javaのregexライブラリでサポートされているすべての構文をリストするのに適しています。すべての構文の意味を詳しく説明するために、 Regular-Expressions.infoサイト が非常に役立つことがわかりました。

46
erickson

Google GuavaCharMatcher を使用すると、すべての non-printable 文字を削除して、すべてのASCII文字(アクセントを削除):

String printable = CharMatcher.INVISIBLE.removeFrom(input);
String clean = CharMatcher.ASCII.retainFrom(printable);

それが本当に必要かどうかはわかりませんが、質問のサンプルデータでエスケープシーケンスとして表現されているものはすべて削除されます。

15

私はそれが多分遅いことを知っていますが、将来の参考のために:

String clean = str.replaceAll("\\P{Print}", "");

印刷できないすべての文字を削除しますが、\n(ラインフィード)、\t(タブ)、\r(キャリッジリターン)が含まれ、これらの文字を保持したい場合があります。

その問題には、反転ロジックを使用します。

String clean = str.replaceAll("[^\\n\\r\\t\\p{Print}]", "");
10
Ivan Pavić

あなたはこのコードを試すことができます:

public String cleanInvalidCharacters(String in) {
    StringBuilder out = new StringBuilder();
    char current;
    if (in == null || ("".equals(in))) {
        return "";
    }
    for (int i = 0; i < in.length(); i++) {
        current = in.charAt(i);
        if ((current == 0x9)
                || (current == 0xA)
                || (current == 0xD)
                || ((current >= 0x20) && (current <= 0xD7FF))
                || ((current >= 0xE000) && (current <= 0xFFFD))
                || ((current >= 0x10000) && (current <= 0x10FFFF))) {
            out.append(current);
        }

    }
    return out.toString().replaceAll("\\s", " ");
}

Stringから無効な文字を削除するのに役立ちます。

3

あなたはJava.text.normalizerを使うことができます

1
exception

入力=> "これ\u7279 テキスト\u7279 必要なもの"出力=> "このテキストが必要なもの "

上記のような文字列からUnicode文字を削除しようとしている場合、このコードは機能します

Pattern unicodeCharsPattern = Pattern.compile("\\\\u(\\p{XDigit}{4})");
Matcher unicodeMatcher = unicodeChars.matcher(data);
String cleanData = null;
if (unicodeMatcher.find()) {
    cleanData = unicodeMatcher.replaceAll("");
}
0