Ersetzen Sie Nicht-ASCII-Zeichen aus der Zeichenfolge

74

Ich habe Strings A função, Ãugentin denen ich brauche wie zu ersetzen Zeichen ç, ã, Ãmit leeren Saiten.

Wie kann ich nur diese Nicht-ASCII-Zeichen abgleichen?

Ich benutze eine Funktion

public static String matchAndReplaceNonEnglishChar(String tmpsrcdta)
    {
        String newsrcdta = null;
        char array[] = Arrays.stringToCharArray(tmpsrcdta);
        if (array == null)
            return newsrcdta;

        for (int i = 0; i < array.length; i++)
        {           
            int nVal = (int)array[i];
            boolean bISO = Character.isISOControl(array[i]); // Is character ISO control
            boolean bIgnorable = Character.isIdentifierIgnorable(array[i]); // Is Ignorable identifier
            // Remove tab and other unwanted characters..
            if (nVal == 9 || bISO || bIgnorable)
                array[i] = ' ';
            else if (nVal > 255)
                array[i] = ' ';
        }
        newsrcdta = Arrays.charArrayToString(array);

        return newsrcdta;
    }

aber es funktioniert nicht richtig ... welche Verbesserung es benötigt ... hier habe ich ein weiteres Problem ist, dass die letzte Zeichenfolge durch Leerzeichen ersetzt wird, die das zusätzliche Leerzeichen in der Zeichenfolge erzeugen.

rahulsri
quelle
2
durch was ersetzen ??????
dku.rajkumar

Antworten:

153

Dadurch werden alle Nicht- ASCII- Buchstaben gesucht und ersetzt :

String resultString = subjectString.replaceAll("[^\\x00-\\x7F]", "");
FailedDev
quelle
danke für die Antwort .. aber dieses "A" kann immer noch nicht durch eine leere Zeichenfolge ersetzt werden.
Rahulsri
3
@rahulsri A ist ein perfekt gültiges ASCII-Zeichen. Warum sollte es ersetzt werden?
FailedDev
@ Dev Ich denke, es ist nicht sichtbar, aber dies ist ein lateinisches Zeichen, dessen Unicode-Wert "\ u00c3" ist.
Rahulsri
@rahulsri Kannst du dies posten, was bitte nicht durch Bearbeiten deiner Frage ersetzt werden kann?
FailedDev
40
Höchstwahrscheinlich möchten Sie auch nicht druckbare Zeichen und Steuerzeichen entfernen. In diesem Fall würden Sie den folgenden regulären Ausdruck verwenden: "[^\\x20-\\x7E]"Oder einfach:"[^ -~]"
Zouppen
80

Die Antwort von FailedDev ist gut, kann aber verbessert werden. Wenn Sie die ASCII-Äquivalente beibehalten möchten, müssen Sie zuerst normalisieren:

String subjectString = "öäü";
subjectString = Normalizer.normalize(subjectString, Normalizer.Form.NFD);
String resultString = subjectString.replaceAll("[^\\x00-\\x7F]", "");

=> will produce "oau"

Auf diese Weise werden Zeichen wie "öäü" "oau" zugeordnet, wodurch zumindest einige Informationen erhalten bleiben. Ohne Normalisierung ist der resultierende String leer.

Michael Böckling
quelle
5
Ihre Antwort ist gut, kann aber verbessert werden. Das Entfernen der Verwendung von Regex in Ihrem Code und das Ersetzen durch eine for-Schleife ist unglaublich schneller (20-40x). Mehr hier: stackoverflow.com/a/15191508/2511884
Saket
Danke für den Tipp. Das Ausmaß des Leistungsunterschieds war unerwartet.
Michael Böckling
2
Sie möchten wahrscheinlich Normalizer.Form.NFKD anstelle von NFD verwenden - NFKD konvertiert Dinge wie Ligaturen in ASCII-Zeichen (z. B. fi zu fi), NFD tut dies nicht.
Brust 8
Normalizer.normalize("ãéío – o áá", Normalizer.Form.NFD).replaceAll("[^\\x00-\\x7F]", "");ergibt "aeio o aa", aber echo "ãéío – o áá" | iconv -f utf8 -t ascii//TRANSLITergibt "aeio - o aa". Gibt es eine Möglichkeit, Java dazu zu bringen, "-" durch "-" wie durch iconv zu ersetzen?
dvlcube
22

Dies wäre die Unicode-Lösung

String s = "A função, Ãugent";
String r = s.replaceAll("\\P{InBasic_Latin}", "");

\p{InBasic_Latin}ist der Unicode-Block, der alle Buchstaben im Unicode-Bereich U + 0000..U + 007F enthält (siehe reguläre Ausdrucksinfo ).

\P{InBasic_Latin} ist das negierte \p{InBasic_Latin}

Stema
quelle
5
(Hinweis für alle, die wie ich verwirrt sind: Der Großbuchstabe \ P ist Negation.)
ShreevatsaR
2
@ user1187719, Sie könnten genauer sein als "Dies funktioniert nicht". Diese Antwort hat bereits einige positive Stimmen erhalten, so dass sie nicht völlig nutzlos sein kann. Natürlich, wenn Sie eine Java-Version vor Java 7 haben , dann stimme ich zu. Unicode in Regex funktioniert dort nicht.
Stema
@stema - Ich habe es in Java 6 ausgeführt, daher enthält Ihre Java 7-Theorie Wasser.
Entropie
es entfernt die Sonderzeichen und "nicht" ersetzt sie durch ASCII-Äquivalent
AL̲̳I
@Ali, ja du hast meine Antwort genau verstanden. Dies ist, was vor 5 Jahren gefragt wurde. Wenn es nicht das ist, was Sie brauchen, gehen Sie mit Michael Böcklings Antwort.
Stema
3

Sie können so etwas versuchen. Der Bereich für Sonderzeichen für Alphabete beginnt bei 192, sodass Sie solche Zeichen im Ergebnis vermeiden können.

String name = "A função";

StringBuilder result = new StringBuilder();
for(char val : name.toCharArray()) {
    if(val < 192) result.append(val);
}
System.out.println("Result "+result.toString());
mmodi
quelle
Warum prüfen Sie gegen 192 und nicht gegen 128 (was wäre die ASCII-Tabelle)? Sie gehen von einer bestimmten Codierung aus (ich denke ISO-8859-1), aber was ist, wenn die Codierung ISO-8859-2 / 3/4/5/7 ist ...? In diesem Bereich der Tabelle befinden sich Buchstaben.
Stema
Ja, dies hängt von der Anzahl der Zeichen ab, die wir zulassen möchten, sowie von der Codierung. Dies ist nur das Beispiel. Wir können Bedingungen basierend auf den erforderlichen Zeichen und der Codierung hinzufügen.
mmodi
1

Oder Sie können die folgende Funktion verwenden, um Nicht-ASCII-Zeichen aus der Zeichenfolge zu entfernen. Sie werden interne Arbeit kennenlernen.

private static String removeNonASCIIChar(String str) {

        StringBuffer buff = new StringBuffer();
        char chars[] = str.toCharArray();

        for (int i = 0; i < chars.length; i++) {

            if (0 < chars[i] && chars[i] < 127) {

                buff.append(chars[i]);
            }

        }
        return buff.toString();

    } 
Rakesh Chaudhari
quelle
0

[Aktualisierte Lösung]

kann mit "Normalize" (Canonical Decomposition) und "replaceAll" verwendet werden, um es durch die entsprechenden Zeichen zu ersetzen.

import java.text.Normalizer;
import java.text.Normalizer.Form;
import java.util.regex.Pattern;

public final class NormalizeUtils {

    public static String normalizeASCII(final String string) {
        final String normalize = Normalizer.normalize(string, Form.NFD);

        return Pattern.compile("\\p{InCombiningDiacriticalMarks}+")
                      .matcher(normalize)
                      .replaceAll("");
    } ...
Elton Sandré
quelle