Konwersja symboli, liter akcentowych na alfabet angielski

Problem polega na tym, że, jak wiecie, na wykresie Unicode są tysiące znaków i chcę przekonwertować wszystkie podobne znaki na litery, które są w alfabecie angielskim.

Na przykład oto kilka konwersji:

ҥ->H
Ѷ->V
Ȳ->Y
Ǭ->O
Ƈ->C
tђє Ŧค๓เℓy --> the Family
...

I widziałem, że istnieje ponad 20 wersji liter A / a. i nie wiem, jak je sklasyfikować. Wyglądają jak igły w stogu siana.

Pełna lista znaków unicode znajduje się na http://www.ssec.wisc.edu / ~tomw/java/unicode.html lub http://unicode.org/charts/charindex.html . Po prostu spróbuj przewijać w dół i zobaczyć odmiany liter.

Jak mogę przekonwertować to wszystko za pomocą Javy? Proszę o pomoc: (

Author: Andreas Petersson, 2009-06-17

12 answers

Reposting my post from Jak usunąć znaki diakrytyczne (akcenty) z ciągu znaków w. NET?

Ta metoda działa dobrze w Javie (wyłącznie w celu usunięcia znaków diakrytycznych akcentów) .

W zasadzie konwertuje wszystkie znaki akcentowane na ich nieakcentowane odpowiedniki, a następnie ich kombinowane znaki diakrytyczne. Teraz możesz użyć wyrażenia regularnego, aby usunąć znaki diakrytyczne.

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

public String deAccent(String str) {
    String nfdNormalizedString = Normalizer.normalize(str, Normalizer.Form.NFD); 
    Pattern pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
    return pattern.matcher(nfdNormalizedString).replaceAll("");
}
 199
Author: hashable,
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 12:34:35

Jest częścią Apache Commons Lang od wersji ver. 3.0.

org.apache.commons.lang3.StringUtils.stripAccents("Añ");

Zwraca An

Zobacz też http://www.drillio.com/en/software-development/java/removing-accents-diacritics-in-any-language/

 72
Author: Ondra Žižka,
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-02-26 12:04:52

Próba "przekonwertowania ich wszystkich" jest złym podejściem do problemu.

Po pierwsze, musisz zrozumieć ograniczenia tego, co próbujesz zrobić. Jak zauważyli inni, znaki diakrytyczne istnieją nie bez powodu: są to zasadniczo unikalne litery w alfabecie tego języka z własnym znaczeniem / dźwiękiem itp.: usunięcie tych znaków jest tak samo jak zastąpienie przypadkowych liter w słowie angielskim. To zanim jeszcze przejdziesz do rozważenia języków cyrylicy i inne teksty oparte na skryptach, takie jak arabski, które po prostu nie mogą być "przekonwertowane" na angielski.

Jeśli musisz , z jakiegokolwiek powodu, konwertować znaki, to jedynym rozsądnym sposobem podejścia do tego jest najpierw zmniejszenie zakresu zadania. Rozważ źródło danych wejściowych - jeśli kodujesz aplikację dla "świata zachodniego" (aby użyć tak dobrego wyrażenia, jak każde inne), jest mało prawdopodobne, że kiedykolwiek będziesz musiał przeanalizować znaki arabskie. Podobnie zestaw znaków Unicode zawiera setki symboli matematycznych i obrazkowych: nie ma (łatwego) sposobu, aby użytkownicy mogli je bezpośrednio wprowadzić, więc można założyć, że mogą być ignorowane.

Wykonując te logiczne kroki, możesz zmniejszyć liczbę możliwych znaków do przetworzenia do punktu, w którym możliwa jest operacja wyszukiwania / zamiany oparta na słowniku. Następnie staje się niewielką ilością nieco nudnej pracy tworzącej słowniki i trywialnym zadaniem do wykonania wymiany. Jeśli twój język obsługuje natywny Znaki Unicode (tak jak robi to Java) i optymalizuje statyczne struktury poprawnie, takie znajdowanie i zastępowanie są zwykle ślepo szybkie.

Wynika to z doświadczenia w pracy nad aplikacją, która była wymagana, aby umożliwić użytkownikom końcowym przeszukiwanie danych bibliograficznych zawierających znaki diakrytyczne. Przygotowanie tablic lookup (jak to było w naszym przypadku) zajęło chyba 1 dzień, aby pokryć wszystkie znaki diakrytyczne dla wszystkich języków zachodnioeuropejskich.

 19
Author: Ian,
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
2012-12-01 01:11:56

Ponieważ kodowanie, które zamienia "rodzinę" w "tђє Ŧค๓เℓy" jest w rzeczywistości losowe i nie podąża za żadnym algorytmem, który może być wyjaśniony przez Informacje o punktach kodowych Unicode, nie ma ogólnego sposobu na rozwiązanie tego algorytmu.

Będziesz musiał zbudować mapowanie znaków Unicode na znaki łacińskie, które przypominają. Prawdopodobnie można to zrobić za pomocą inteligentnego uczenia maszynowego na rzeczywistych glifach reprezentujących Punkty kodowe Unicode. Ale myślę, że wysiłek w tym kierunku byłby większy niż ręczne tworzenie tego mapowania. Zwłaszcza jeśli masz dużą ilość przykładów, z których możesz zbudować swoje mapowanie.

Dla wyjaśnienia: kilka podstawień może być faktycznie rozwiązanych za pomocą danych Unicode (Jak pokazują inne odpowiedzi), ale niektóre litery po prostu nie mają rozsądnego związku z łacińskimi znakami, które przypominają.

Przykłady:

  • "ђ" (u + 0452 cyrylica mała litera DJE) jest bardziej związane z "d" niż z "h", ale jest używany do reprezentowania "h".
  • "Ŧ" (u+0166 łacińska Wielka Litera T z udarem) jest nieco podobne do "T" (jak sama nazwa wskazuje), ale jest używane do reprezentowania "F".
  • "ค" (u+0E04 tajski znak KHO KHWAI) nie jest w ogóle spokrewniony z żadnym łacińskim znakiem i w twoim przykładzie jest używany do reprezentowania "a"
 15
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
2009-09-09 08:55:48

String tested:]}

Testowany:

Ostatni wybór to najlepszy.

 9
Author: cactuschibre,
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-04-12 13:23:35

Pierwotna prośba została już rozpatrzona.

Zamieszczam jednak poniższą odpowiedź dla tych, którzy mogą szukać ogólnego kodu transliteracyjnego do transliteracji dowolnego zestawu znaków na język łaciński/angielski w Javie.

Naiwne znaczenie tranliteracji: Przetłumaczony ciąg w jego ostatecznej formie / docelowym zestawie znaków brzmi jak ciąg w jego oryginalnej formie. Jeśli chcemy transliterować dowolny zestaw znaków na łacinę (alfabety angielskie), to ICU4 (biblioteka ICU4J w Javie) zrobi praca.

Oto fragment kodu w Javie:

    import com.ibm.icu.text.Transliterator; //ICU4J library import

    public static String TRANSLITERATE_ID = "NFD; Any-Latin; NFC";
    public static String NORMALIZE_ID = "NFD; [:Nonspacing Mark:] Remove; NFC";

    /**
    * Returns the transliterated string to convert any charset to latin.
    */
    public static String transliterate(String input) {
        Transliterator transliterator = Transliterator.getInstance(TRANSLITERATE_ID + "; " + NORMALIZE_ID);
        String result = transliterator.transliterate(input);
        return result;
    }
 7
Author: Dayanand Gowda,
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
2014-11-21 11:13:28

Jeśli potrzeba konwersji "òışöç->oeisoc", możesz użyć tego punktu początkowego:

public class AsciiUtils {
    private static final String PLAIN_ASCII =
      "AaEeIiOoUu"    // grave
    + "AaEeIiOoUuYy"  // acute
    + "AaEeIiOoUuYy"  // circumflex
    + "AaOoNn"        // tilde
    + "AaEeIiOoUuYy"  // umlaut
    + "Aa"            // ring
    + "Cc"            // cedilla
    + "OoUu"          // double acute
    ;

    private static final String UNICODE =
     "\u00C0\u00E0\u00C8\u00E8\u00CC\u00EC\u00D2\u00F2\u00D9\u00F9"             
    + "\u00C1\u00E1\u00C9\u00E9\u00CD\u00ED\u00D3\u00F3\u00DA\u00FA\u00DD\u00FD" 
    + "\u00C2\u00E2\u00CA\u00EA\u00CE\u00EE\u00D4\u00F4\u00DB\u00FB\u0176\u0177" 
    + "\u00C3\u00E3\u00D5\u00F5\u00D1\u00F1"
    + "\u00C4\u00E4\u00CB\u00EB\u00CF\u00EF\u00D6\u00F6\u00DC\u00FC\u0178\u00FF" 
    + "\u00C5\u00E5"                                                             
    + "\u00C7\u00E7" 
    + "\u0150\u0151\u0170\u0171" 
    ;

    // private constructor, can't be instanciated!
    private AsciiUtils() { }

    // remove accentued from a string and replace with ascii equivalent
    public static String convertNonAscii(String s) {
       if (s == null) return null;
       StringBuilder sb = new StringBuilder();
       int n = s.length();
       for (int i = 0; i < n; i++) {
          char c = s.charAt(i);
          int pos = UNICODE.indexOf(c);
          if (pos > -1){
              sb.append(PLAIN_ASCII.charAt(pos));
          }
          else {
              sb.append(c);
          }
       }
       return sb.toString();
    }

    public static void main(String args[]) {
       String s = 
         "The result : È,É,Ê,Ë,Û,Ù,Ï,Î,À,Â,Ô,è,é,ê,ë,û,ù,ï,î,à,â,ô,ç";
       System.out.println(AsciiUtils.convertNonAscii(s));
       // output : 
       // The result : E,E,E,E,U,U,I,I,A,A,O,e,e,e,e,u,u,i,i,a,a,o,c
    }
}

JDK 1.6 dostarcza Javę.tekst.Klasa Normalizer, która może być użyta do tego zadania.

Zobacz przykład tutaj

 6
Author: RealHowTo,
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
2009-06-17 22:33:32

Problem z" konwersją " arbitralnego Unicode do ASCII polega na tym,że znaczenie znaku jest zależne od kultury. Na przykład "ß" dla osoby niemieckojęzycznej powinno być zamienione na "ss", podczas gdy anglojęzyczny prawdopodobnie przekształci je na "B".

Dodaj do tego fakt, że Unicode ma wiele punktów kodu dla tych samych glifów.

W rezultacie jedynym sposobem na to jest stworzenie ogromnej tabeli z każdym znakiem Unicode i znakiem ASCII, który chcesz przekonwertować za. Skrót można wykonać normalizując znaki z akcentami do normalizacji w postaci KD, ale nie wszystkie znaki normują się do ASCII. Ponadto Unicode nie określa, które części glifu są "akcentami".

Oto mały fragment aplikacji, która to robi:

switch (c)
{
    case 'A':
    case '\u00C0':  //  À LATIN CAPITAL LETTER A WITH GRAVE
    case '\u00C1':  //  Á LATIN CAPITAL LETTER A WITH ACUTE
    case '\u00C2':  //  Â LATIN CAPITAL LETTER A WITH CIRCUMFLEX
    // and so on for about 20 lines...
        return "A";
        break;

    case '\u00C6'://  Æ LATIN CAPITAL LIGATURE AE
        return "AE";
        break;

    // And so on for pages...
}
 5
Author: Dour High Arch,
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-10 18:13:33

Możesz spróbować użyć unidecode, który jest dostępny jako Ruby gem oraz jako moduł Perla na cpan. Zasadniczo działa jako ogromna tabela wyszukiwania, w której każdy punkt kodu unicode odnosi się do znaku lub łańcucha znaków ascii.

 4
Author: Daniel Vandersluis,
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
2009-06-17 19:14:07

Nie ma łatwego lub ogólnego sposobu, aby zrobić to, co chcesz, ponieważ jest to tylko twoja subiektywna opinia, że te litery wyglądają tak, jak litery łacińskie, na które chcesz przekonwertować. Są to w rzeczywistości oddzielne litery z własnymi odrębnymi nazwami i dźwiękami, które po prostu pozornie wyglądają jak łacińska litera.

Jeśli chcesz tę konwersję, musisz utworzyć własną tabelę tłumaczeń na podstawie tego, na jakie litery łacińskie uważasz, że nie-łacińskie litery powinny zostać przekonwertowane.

(jeśli chcesz tylko usunąć znaki diakrytyczne, w tym wątku znajdziesz kilka odpowiedzi: Jak usunąć znaki diakrytyczne (akcenty) z ciągu znaków w. Net? jakkolwiek opisujesz bardziej ogólny problem)

 4
Author: JacquesB,
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 10:31:29

Jestem spóźniony na imprezę, ale po dzisiejszym problemie znalazłem odpowiedź bardzo dobrą:

String asciiName = Normalizer.normalize(unicodeName, Normalizer.Form.NFD)
    .replaceAll("[^\\p{ASCII}]", "");

Odniesienie: https://stackoverflow.com/a/16283863

 4
Author: Francisco Junior,
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:54:44

Następująca Klasa robi sztuczkę:

org.apache.lucene.analysis.miscellaneous.ASCIIFoldingFilter
 2
Author: TomWolk,
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-06-26 10:50:43