2009-11-04 12 views
21

Załóżmy, że mam ciąg znaków, który zawiera Ü. Jak znaleźć wszystkie te znaki Unicode? Czy powinienem przetestować swój kod? Jak to zrobić?Jak wykrywać znaki Unicode w ciągu znaków Java?

Na przykład, biorąc pod uwagę ciąg "AÜXÜ", chciałbym przekształcić go na "AYXY". Chciałbym zrobić to samo dla innych znaków unicode i nie chciałbym ich przechowywać na jakiejś mapie tłumaczeń.

+3

Skąd wiadomo, na co † będzie mapować bez własnej mapy?Nie ma prostego mapowania i podejrzewam, że w różnych językach każde mapowanie może się różnić – Mark

+0

tak naprawdę można to zrobić, patrząc na znaki jeden po drugim. To zależy od "zasięgu" znaku, ale jest to cichy, niski poziom i zakładam, że istnieje już coś, co pozwoli osiągnąć to zadanie. zobacz http://en.wikipedia.org/wiki/Unicode – Aif

+0

Zobacz również rozwiązanie tutaj: https://rosettacode.org/wiki/Strip_control_codes_and_extended_characters_from_a_string#Java – Stan

Odpowiedz

15

Definicja "znaków Unicode" jest niejasna, ale zostanie przeniesiona do oznacza znaki UTF-8 nie objęte standardem ISO 8859 charset. Jeśli tak jest w twoim przypadku, przeprowadź pętlę przez wszystkie znaki w łańcuchu i przetestuj jego punkt kodowy, aby określić, czy znajduje się on w podanym zestawie znaków.

Można również użyć Map<Character, Character> i znaków na mapie, które zawierają pasujące klucze. Na przykład:

Map<Character, Character> charReplacementMap = new HashMap<Character, Character>() {{ 
    put('Ü', 'Y'); 
    // Put more here. 
}}; 

String originalString = "AÜAÜ"; 
StringBuilder builder = new StringBuilder(); 

for (char currentChar : originalString.toCharArray()) { 
    Character replacementChar = charReplacementMap.get(currentChar); 
    builder.append(replacementChar != null ? replacementChar : currentChar); 
} 

String newString = builder.toString(); 

Czy masz na myśli "wszystkie postacie ze znakami diakrytycznymi"? Jeśli tak, a następnie użyć java.text.Normalizer usunąć znaki diakrytyczne:

/** 
* Remove any diacritical marks (accents like ç, ñ, é, etc) from 
* the given string (so that it returns plain c, n, e, etc). 
* @param string The string to remove diacritical marks from. 
* @return The string with removed diacritical marks, if any. 
*/ 
public static String removeDiacriticalMarks(String string) { 
    return Normalizer.normalize(string, Form.NFD) 
     .replaceAll("\\p{InCombiningDiacriticalMarks}+", ""); 
} 

Jedna pułapka, U staną U, a nie Y. Nie wiem, czy to właśnie Ty jesteś po. Jeśli chcesz zastąpić wyraźną postacią, naprawdę musisz utworzyć mapowanie. Oczywiście, jest to żmudne dzieło, ale zostało zrobione w krótszym czasie niż było to konieczne.

+0

Tak zwykle robiłem. Ale wymagałoby to dodania każdego znaku na mapie. – Geo

+0

Nie widzę żadnej innej skutecznej opcji zastąpienia pewnej postaci przez pewną postać i tej dla więcej niż jednej postaci. – BalusC

+1

Jeśli nie dodasz każdego znaku do mapy, w jaki sposób zdefiniujesz zamiennik? Czy chcesz, aby wszystkie znaki spoza ASCII zostały zastąpione przez jedną postać ascii? –

11

Można przejść na odwrót i zapytać, czy postać jest postacią ascii.

public static boolean isAscii(char ch) { 
    return ch < 128; 
} 

Będziesz musiał przeanalizować ciąg znaków char przez oczywiście.

(metoda ta jest od commons-lang Charutils który zawiera mnóstwo przydatnych metod znaków)

1

Nie jestem pewien, ze swoim przykładzie, co próbujesz zrobić - jeśli jesteś po prostu staramy się zastąpić wszystkie nie-ASCII wartości za pomocą Y, możesz przeszukać ciąg szukający punktów kodowych spoza zakresu od 0 do 127 i zastąpić je kodami Y.

12

mogli Państwo pętla za pośrednictwem łańcucha i dla każdego połączenia znaków

If (Character.UnicodeBlock.of(c) != Character.UnicodeBlock.BASIC_LATIN) { 
// replace with Y 
} 
+0

Dobry do testowania codepunktów, ale nie mam wrażenia, że ​​chce zastąpić * każdy * znak przez Y. – BalusC

+0

No cóż, mówi unicode znaków przez to rozumiem, że prawdopodobnie oznacza zastąpić wszystkie znaki non-ascii Y. niezależnie od tego, – jitter

2

To nie jest dla mnie jasne, co dokładnie jest zdobyte przez przekształcenie „AÜXÜ” na „AYXY”. Czy to dlatego, że Ü jest wymawiane jak w danym języku? Jaki język? I jakie inne zasady mogą mieć zastosowanie?


Pod względem terminologii ...

"a" 

Powyższe jest ciągiem znaków Unicode. Zawiera pojedynczy kodowany znak UTF-16.

Jeśli chcesz ograniczyć zakres znaków do alfabetu angielskiego, spójrz na numer Normalization performed in this answer.

+0

To był tylko przykład zastępczy. Naprawdę zastąpię znak przez _ _XX_' :) – Geo

0

Klasa Character oferuje również kilka interesujących metod. Spójrz na to.

Character.UnicodeBlock.of('a') == Character.UnicodeBlock.BASIC_LATIN; //true 

Character.UnicodeBlock.of('�') == Character.UnicodeBlock.BASIC_LATIN; //false 
Powiązane problemy