2010-03-30 44 views
10

chúng tôi chấp nhận tất cả các loại ký tự quốc gia trong chuỗi UTF-8 trên đầu vào và chúng tôi cần chuyển đổi chúng thành chuỗi ASCII trên đầu ra cho một số mục đích sử dụng cũ. (Chúng tôi không chấp nhận ký tự Trung Quốc và Nhật Bản, chỉ có ngôn ngữ châu Âu)Chuyển đổi UTF-8 sang ASCII với các bổ sung

Chúng tôi đã một tiện ích nhỏ để thoát khỏi tất cả các dấu:

public static final String toBaseCharacters(final String sText) { 
    if (sText == null || sText.length() == 0) 
     return sText; 

    final char[] chars = sText.toCharArray(); 
    final int iSize = chars.length; 
    final StringBuilder sb = new StringBuilder(iSize); 

    for (int i = 0; i < iSize; i++) { 
     String sLetter = new String(new char[] { chars[i] }); 
     sLetter = Normalizer.normalize(sLetter, Normalizer.Form.NFC); 

     try { 
      byte[] bLetter = sLetter.getBytes("UTF-8"); 
      sb.append((char) bLetter[0]); 
     } catch (UnsupportedEncodingException e) { 
     } 
    } 
    return sb.toString(); 
} 

Câu hỏi đặt ra là làm thế nào để thay thế tất cả các s nhọn Đức (ß, Đ, đ) và các ký tự khác thông qua phương pháp chuẩn hóa ở trên, với các chất bổ sung (trong trường hợp ß, bổ sung có thể là "ss" và trong trường hợp bổ sung od Đ sẽ là "D" hoặc "Dj").

Có cách nào đơn giản để làm điều đó, mà không có hàng triệu .replaceAll() gọi?

Ví dụ: Đonardan = Djonardan, Blaß = Blass, v.v.

Chúng tôi có thể thay thế tất cả các ký tự "có vấn đề" bằng khoảng trống, nhưng muốn tránh điều này để làm cho đầu ra tương tự như đầu vào càng tốt.

Cảm ơn bạn đã trả lời của bạn,

Bozo

+5

Lưu ý rằng không có bản đồ duy nhất: Trong tiếng Đức, "ö" được thay thế bởi "oe", trong khi bằng tiếng Thụy Điển, "ö" được thay thế bằng "o". – Heinzi

+0

Bạn sẽ cần phải có chức năng này trong một tham số ngôn ngữ và có thể có một ngôn ngữ mặc định. Hoặc dành thời gian cố gắng tìm ra cách quyết định chuỗi ngôn ngữ nào sẽ đến, nhưng điều đó sẽ phanh nếu chuỗi không đủ dài. một trong hai cách, có vẻ như bạn sẽ cần một cái nhìn lên bảng của một số loại. Hãy để ứng dụng của bạn đi qua toàn bộ chuỗi, kiểm tra từng ký tự và tìm kiếm những gì nó cần được đổi chỗ. – thecoshman

+0

Một tùy chọn khác có thể thay thế "ö" bằng "o:" như một loại "dấu phụ của người nghèo". –

Trả lời

0

Có một số cách đơn giản để làm điều đó, mà không cần triệu .replaceAll() gọi?

Nếu bạn chỉ hỗ trợ ngôn ngữ châu Âu, tiếng Latinh, khoảng 100 là đủ; điều đó chắc chắn có thể thực hiện được: Hãy lấy Unicode charts cho Latin-1 SupplementLatin Extended-A và bắt đầu bữa tiệc String.replace. :-)

+1

Tôi không thể tin rằng không ai làm điều này, tạo ra một vài bản đồ và cho biết, đây là một trong những người thích nó theo cách này hoặc cách khác, mở rộng nó nếu bạn muốn một số sửa đổi theo nhu cầu của bạn. – bozo

2

Bạn muốn sử dụng ICU4J. Nó bao gồm các lớp học com.ibm.icu.text.Transliterator, mà dường như có thể làm những gì bạn đang tìm kiếm.

+1

Ngoại trừ các phiên dịch viên ICU4J tôi đã thử là cực kỳ không chính xác (latin, cyrillic và hangul), bạn cho rằng trình chuyển ngữ chính xác nào bạn nghĩ sẽ đáp ứng yêu cầu ban đầu? Tôi không thể tìm thấy bất cứ điều gì dường như phù hợp. – jarnbjo

+0

Tôi đã thử ICU4J và nó quá phức tạp đến mức tôi thậm chí không thể chạy nó. – bozo

1

Tôi đang sử dụng một cái gì đó như thế này:

Transliterator transliterator = Transliterator.getInstance("Any-Latin; Upper; Lower; NFD; [:Nonspacing Mark:] Remove; NFC", Transliterator.FORWARD); 
1

Dưới đây là chuyển đổi của tôi trong đó sử dụng Lucene ...

private final KeywordTokenizer keywordTokenizer = new KeywordTokenizer(new StringReader("")); 
private final ASCIIFoldingFilter asciiFoldingFilter = new ASCIIFoldingFilter(keywordTokenizer); 
private final TermAttribute termAttribute = (TermAttribute) asciiFoldingFilter.getAttribute(TermAttribute.class); 

public String process(String line) 
{ 
    if (line != null) 
    { 
     try 
     { 
      keywordTokenizer.reset(new StringReader(line)); 
      if (asciiFoldingFilter.incrementToken()) 
      { 
       return termAttribute.term(); 
      } 
     } 
     catch (IOException e) 
     { 
      logger.warn("Failed to parse: " + line, e); 
     } 
    } 
    return null; 
} 
Các vấn đề liên quan