2010-04-16 77 views
5

Tôi thích thay thế một bộ ký tự nhất định của một chuỗi bằng ký tự thay thế tương ứng theo cách hiệu quả.Làm thế nào để thay thế các ký tự trong một chuỗi java?

Ví dụ:

String sourceCharacters = "šđćčŠĐĆČžŽ"; 
String targetCharacters = "sdccSDCCzZ"; 

String result = replaceChars("Gračišće", sourceCharacters , targetCharacters); 

Assert.equals(result,"Gracisce") == true; 

Có là cách hiệu quả hơn để sử dụng phương pháp replaceAll của lớp String?

ý tưởng đầu tiên của tôi là:

final String s = "Gračišće"; 
String sourceCharacters = "šđćčŠĐĆČžŽ"; 
String targetCharacters = "sdccSDCCzZ"; 

// preparation 
final char[] sourceString = s.toCharArray(); 
final char result[] = new char[sourceString.length]; 
final char[] targetCharactersArray = targetCharacters.toCharArray(); 

// main work 
for(int i=0,l=sourceString.length;i<l;++i) 
{ 
    final int pos = sourceCharacters.indexOf(sourceString[i]); 
    result[i] = pos!=-1 ? targetCharactersArray[pos] : sourceString[i]; 
} 

// result 
String resultString = new String(result); 

Bất kỳ ý tưởng?

Btw, các ký tự UTF-8 đang gây ra sự cố, với US_ASCII nó hoạt động tốt.

Trả lời

14

Bạn có thể sử dụng java.text.Normalizer và một lần chụp regex để loại bỏ diacritics trong đó có tồn tại nhiều hơn nhiều hơn số tiền bạn đã thu thập được.

Dưới đây là một SSCCE, copy'n'paste'n'run nó trên Java 6:

package com.stackoverflow.q2653739; 

import java.text.Normalizer; 
import java.text.Normalizer.Form; 

public class Test { 

    public static void main(String... args) { 
     System.out.println(removeDiacriticalMarks("Gračišće")); 
    } 

    public static String removeDiacriticalMarks(String string) { 
     return Normalizer.normalize(string, Form.NFD) 
      .replaceAll("\\p{InCombiningDiacriticalMarks}+", ""); 
    } 
} 

này nên mang

Gracisce

Ít nhất, nó làm ở đây tại Eclipse với giao diện điều khiển nhân vật mã hóa được đặt thành UTF-8 (Cửa sổ> Tùy chọn> Chung> Vùng làm việc> Mã hóa tệp văn bản). Đảm bảo rằng điều tương tự cũng được đặt trong môi trường của bạn.

Là một thay thế, duy trì một Map<Character, Character>:

Map<Character, Character> charReplacementMap = new HashMap<Character, Character>(); 
charReplacementMap.put('š', 's'); 
charReplacementMap.put('đ', 'd'); 
// Put more here. 

String originalString = "Gračišće"; 
StringBuilder builder = new StringBuilder(); 

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

String newString = builder.toString(); 
+0

với giải pháp này tôi nhận được: GraA? IA¡Ae. và btw, tôi muốn thay thế không chỉ các ký tự dấu phụ mà còn thay thế một số ngôn ngữ khác. vì vậy tôi thực sự muốn biết một giải pháp hoạt động cho một bản đồ tùy ý. – ManBugra

+1

Chính xác. Vấn đề là các dấu phụ đôi khi được kết hợp, đôi khi không, và chuỗi ký tự thay thế ký tự bị nhầm lẫn bởi vì có hai ký tự chứ không phải một ký tự. –

+0

@Mr. Sáng bóng và mới: vâng, System.out.println ("š". ToCharArray(). Length); kết quả đầu ra '2' – ManBugra

0

Tôi muốn sử dụng phương pháp replace trong một vòng lặp đơn giản.

String sourceCharacters = "šđćčŠĐĆČžŽ"; 
String targetCharacters = "sdccSDCCzZ"; 

String s = "Gračišće"; 
for (int i=0 ; i<sourceCharacters.length() ; i++) 
    s = s.replace(sourceCharacters.charAt[i], targetCharacters.charAt[i]); 

System.out.println(s); 
+0

mỗi lần lặp lại sẽ tạo một đối tượng chuỗi mới.sẽ được tốt đẹp để làm điều đó 'tại chỗ' – ManBugra

+0

Thứ nhất, mỗi lần lặp lại chỉ làm cho một đối tượng mới nếu một thay đổi được thực hiện; nếu nhân vật được tìm kiếm không có ở đó, đối tượng gốc sẽ được trả về. Thứ hai, nó là * xa * khó chịu hơn để viết mã này bằng cách sử dụng 'StringBuilder' hoặc' StringBuffer' vì bạn phải tự làm tất cả công việc; kể từ khi quản lý bộ nhớ của Java được điều chỉnh cho doanh thu đối tượng nhanh chóng anyway, nó dễ dàng hơn để làm điều đó theo cách tôi cho thấy thay vì cố gắng tìm ra cách để có hiệu quả. Bạn luôn có thể tối ưu hóa sau này nếu thực sự cần thiết (nghĩa là nếu đó là nút cổ chai thực sự). –

+0

có bạn đang ở ngay điểm đầu tiên của bạn. nhưng tôi không đồng ý với thứ hai của bạn. bạn viết mã hiệu quả một lần, thậm chí nó gây phiền nhiễu, và sử dụng lại nó. dù sao BalusC đã giải quyết được câu đố. – ManBugra

Các vấn đề liên quan