2010-03-09 34 views
6

Vấn đề: Tôi có hai chuỗi chiều rộng cố định từ một hệ thống bên ngoài. Đầu tiên chứa các ký tự cơ sở (như a-z), ký tự thứ hai (MAY) có chứa dấu phụ được nối thêm vào chuỗi đầu tiên để tạo các ký tự thực.Chuyển đổi hai ký tự ascii thành ký tự 'tương ứng' của chúng mở rộng biểu diễn ascii

string asciibase = "Dutch has funny chars: a,e,u"; 
string diacrits = "      ' \" \""; 

//no clue what to do 

string result = "Dutch has funny chars: á,ë,ü"; 

Tôi có thể viết một tìm kiếm lớn và thay thế cho tất cả các ký tự + dấu khác nhau nhưng hy vọng điều gì đó thanh lịch hơn một chút.

Ai đó có manh mối về cách sửa lỗi này? Đã thử nó với tính toán các giá trị thập phân, sử dụng string.Normalize (C#) nhưng không có kết quả. Ngoài ra, Google đã không thực sự bật lên với một cái gì đó.

+0

Bạn đang tìm kiếm đối diện của string.Normalize, tôi e rằng không có phương pháp nội trang nào để có được thứ bạn muốn ... –

+0

Tôi nghĩ rằng sau khi bình thường hóa, nó chỉ là dấu phụ của anh ấy không phải là ký tự kết hợp nó không hoạt động. –

Trả lời

1

tôi không thể tìm thấy một giải pháp dễ dàng ngoại trừ sử dụng các bảng tra cứu:

public void TestMethod1() 
{ 
    string asciibase = "Dutch has funny chars: a,e,u"; 
    string diacrits = "      ' \" \""; 
    var merged = DiacritMerger.Merge(asciibase, diacrits); 
} 

[EDIT: Đơn giản hóa mã sau khi gợi ý trong các câu trả lời từ @JonB và @Oliver]

public class DiacritMerger 
{ 
    static readonly Dictionary<char, char> _lookup = new Dictionary<char, char> 
         { 
          {'\'', '\u0301'}, 
          {'"', '\u0308'} 
         }; 

    public static string Merge(string asciiBase, string diacrits) 
    { 
     var combined = asciiBase.Zip(diacrits, (ascii, diacrit) => DiacritVersion(diacrit, ascii)); 
     return new string(combined.ToArray()); 
    } 

    private static char DiacritVersion(char diacrit, char character) 
    { 
     char combine; 
     return _lookup.TryGetValue(diacrit, out combine) ? new string(new [] {character, combine}).Normalize()[0] : character; 
    } 
} 
1

Vấn đề là, các dấu phụ được chỉ định phải được phân tích cú pháp rõ ràng, làm cho các điểm hai không tồn tại duy nhất và do đó các dấu ngoặc kép được sử dụng cho trường hợp này. Vì vậy, để hoàn thành vấn đề của bạn, bạn không có bất kỳ cơ hội nào khác để thực hiện từng trường hợp cần thiết.

Đây là một điểm khởi đầu để có được một đầu mối ...

public SomeFunction() 
    { 
     string asciiChars = "Dutch has funny chars: a,e,u"; 
     string diacrits = "      ' \" \""; 

     var combinedChars = asciiChars.Zip(diacrits, (ascii, diacrit) => 
     { 
      return CombineChars(ascii, diacrit); 
     }); 

     var Result = new String(combinedChars.ToArray()); 
    } 

    private char CombineChars(char ascii, char diacrit) 
    { 
     switch (diacrit) 
     { 
      case '"': 
       return AddDoublePoints(ascii); 
      case '\'': 
       return AddAccent(ascii); 
      default: 
       return ascii; 
     } 
    } 

    private char AddDoublePoints(char ascii) 
    { 
     switch (ascii) 
     { 
      case 'a': 
       return 'ä'; 
      case 'o': 
       return 'ö'; 
      case 'u': 
       return 'ü'; 
      default: 
       return ascii; 
     } 
    } 

    private char AddAccent(char ascii) 
    { 
     switch (ascii) 
     { 
      case 'a': 
       return 'á'; 
      case 'o': 
       return 'ó'; 
      default: 
       return ascii; 
     } 
    } 
} 

Các IEnumerable.Zip đã là implemented in .Net 4, nhưng để có được nó trong 3,5 bạn sẽ cần mã này (taken from Eric Lippert):

public static class IEnumerableExtension 
{ 
    public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult> 
     (this IEnumerable<TFirst> first, 
     IEnumerable<TSecond> second, 
     Func<TFirst, TSecond, TResult> resultSelector) 
    { 
     if (first == null) throw new ArgumentNullException("first"); 
     if (second == null) throw new ArgumentNullException("second"); 
     if (resultSelector == null) throw new ArgumentNullException("resultSelector"); 
     return ZipIterator(first, second, resultSelector); 
    } 

    private static IEnumerable<TResult> ZipIterator<TFirst, TSecond, TResult> 
     (IEnumerable<TFirst> first, 
     IEnumerable<TSecond> second, 
     Func<TFirst, TSecond, TResult> resultSelector) 
    { 
     using (IEnumerator<TFirst> e1 = first.GetEnumerator()) 
     using (IEnumerator<TSecond> e2 = second.GetEnumerator()) 
      while (e1.MoveNext() && e2.MoveNext()) 
       yield return resultSelector(e1.Current, e2.Current); 
    } 
} 
+0

Giải pháp bạn đang đưa ra là cách dễ dàng nhất mà tôi tìm thấy - nhưng cũng là vụ giết não nhiều nhất ... Tôi giữ nó cho phương sách cuối cùng;) –

+1

Sau khi đọc các câu trả lời khác, bạn có thể tìm thấy một số giải pháp tốt tất cả chúng (như Mikael đã làm trong bài viết của anh) theo một cách nào đó. – Oliver

4

Chuyển đổi dấu các giá trị unicode phù hợp từ Unicode kết hợp dấu phụ dao động:

http://www.unicode.org/charts/PDF/U0300.pdf

Sau đó tát các char và dấu phụ của nó với nhau ví dụ đối với e-cấp tính, U + 0065 = "e" và U + 0301 = cấp tính.

String s = "\u0065\u0301"; 

Sau đó:

string normalisedString = s.Normalize(); 

sẽ kết hợp hai thành một chuỗi mới.

0

Tôi không biết C# hoặc các thư viện chuẩn của nó, nhưng một phương pháp thay thế có thể là sử dụng một thứ như trình phân tích cú pháp/đối tượng ký tự/HTML/SGML/XML hiện có, hoặc nếu bạn thực sự trình bày nó trình duyệt, không có gì!

Pseudo code:

for(i=0; i < strlen(either_string); i++) { 
    if isspace(diacrits[i]) { 
    output(asciibase[i]); 
    }else{ 
    output("&"); 
    output(asciibase[i]); 
    switch (diacrits[i]) { 
     case '"' : output "uml"; break; 
     case '^' : output "circ"; break; 
     case '~' : output "tilde"; break; 
     case 'o' : output "ring"; break; 
     ... and so on for each "code" in the diacrits modifier 
     ... (for acute, grave, cedil, lig, ...) 
    } 
    output(";"); 
    } 
} 

Như vậy, A + o ->&Aring;, u + " ->&uuml; và vân vân.

Nếu bạn có thể phân tích cú pháp các thực thể html, sau đó bạn nên ở nhà miễn phí và thậm chí di động giữa các bộ ký tự!

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