2009-01-31 76 views
11

Tôi có một đối tượng chuỗiLàm thế nào để chuyển đổi (chuyển ngữ) một chuỗi từ utf8 sang ASCII (byte đơn) trong C#?

"với nhiều nhân vật và nhân vật thậm chí đặc biệt"

Tôi cố gắng để sử dụng

UTF8Encoding utf8 = new UTF8Encoding(); 
ASCIIEncoding ascii = new ASCIIEncoding(); 

đối tượng để chuyển đổi chuỗi để ascii. Tôi có thể nhờ ai đó mang chút ánh sáng đến nhiệm vụ đơn giản này, đó là săn lùng buổi chiều của tôi.

EDIT 1: Những gì chúng tôi đang cố gắng hoàn thành là loại bỏ các ký tự đặc biệt như một số dấu nháy đơn đặc biệt của cửa sổ. Mã mà tôi đăng dưới đây như một câu trả lời sẽ không giải quyết được điều đó. Về cơ bản

O'Brian sẽ trở thành O? Brian. trong đó 'là một trong các dấu nháy đơn đặc biệt

+0

Lưu ý rằng nếu bạn muốn thay thế ký tự có dấu với các khoản tương đương không có giọng của họ, bạn có thể sử dụng str.Normalize (NormalizationForm.FormKD) – yoyo

Trả lời

19

Đây là câu trả lời cho câu hỏi khác của bạn, có vẻ như nó đã bị xóa .... điểm vẫn đứng.

Trông giống như classic Unicode to ASCII issue. Bí quyết là tìm số trong đó nó đang diễn ra.

.NET hoạt động tốt với Unicode, giả sử it's told it's Unicode để bắt đầu (hoặc để mặc định).

My đoán là ứng dụng nhận mà bạn không thể xử lý. Vì vậy, tôi có thể sử dụng ASCIIEncoderwith một EncoderReplacementFallback với String.Empty:

using System.Text; 

string inputString = GetInput(); 
var encoder = ASCIIEncoding.GetEncoder(); 
encoder.Fallback = new EncoderReplacementFallback(string.Empty); 

byte[] bAsciiString = encoder.GetBytes(inputString); 

// Do something with bytes... 
// can write to a file as is 
File.WriteAllBytes(FILE_NAME, bAsciiString); 
// or turn back into a "clean" string 
string cleanString = ASCIIEncoding.GetString(bAsciiString); 
// since the offending bytes have been removed, can use default encoding as well 
Assert.AreEqual(cleanString, Default.GetString(bAsciiString)); 

Tất nhiên, trong những ngày cũ, chúng tôi chỉ lặp dù và loại bỏ bất kỳ ký tự greater than 127 ... tốt, những người chúng tôi ở Mỹ ít nhất. ;)

+4

Cảm ơn nó đã hoạt động hoàn hảo. Tôi chỉ phải thực hiện một thay đổi nhỏ. Encoding encoder = ASCIIEncoding.GetEncoding ("us-ascii", mới EncoderReplacementFallback (string.Empty), new DecoderExceptionFallback()); – Geo

+0

+1 cho EncoderReplacementFallback - Tôi chưa bao giờ nghe nói về điều đó trước đây. Yêu nó. –

+0

'EncoderReplacementFallback' với dấu chấm hỏi là mặc định. Trong trường hợp này, có vẻ như một "mất mát tốt hơn" là mong muốn. Một dự phòng ngoại lệ là hữu ích khi lossy là không thể chấp nhận được (mà IMHO sẽ là mặc định). –

12

Tôi đã có thể tìm ra. Trong trường hợp ai đó muốn biết bên dưới mã làm việc cho tôi:

ASCIIEncoding ascii = new ASCIIEncoding(); 
byte[] byteArray = Encoding.UTF8.GetBytes(sOriginal); 
byte[] asciiArray = Encoding.Convert(Encoding.UTF8, Encoding.ASCII, byteArray); 
string finalString = ascii.GetString(asciiArray); 

Hãy cho tôi biết nếu có cách nào đơn giản hơn.

+0

Nó đáng chú ý là nếu chuỗi chứa các ký tự mà không thể được đại diện trong ASCII, nó sẽ không phải là cùng một chuỗi sau khi chuyển đổi. Nó có thể thiếu các ký tự đó hoặc nó có thể trở nên bị cắt xén, tùy thuộc vào cách Encoding.Convert hoạt động (mà tôi không biết). –

+0

Thực ra tôi chỉ thử nghiệm một số kịch bản và những gì bạn đang nói là đúng sự thật. Bạn có biết cách vượt qua giới hạn này không. Ví dụ: nếu tôi có một trong các dấu nháy đơn đặc biệt để thay thế bằng dấu nháy đơn chung. – Geo

7

Đối với bất kỳ ai thích Phương thức mở rộng, ứng dụng này thực hiện thủ thuật cho chúng tôi.

using System.Text; 

namespace System 
{ 
    public static class StringExtension 
    { 
     private static readonly ASCIIEncoding asciiEncoding = new ASCIIEncoding(); 

     public static string ToAscii(this string dirty) 
     { 
      byte[] bytes = asciiEncoding.GetBytes(dirty); 
      string clean = asciiEncoding.GetString(bytes); 
      return clean; 
     } 
    } 
} 

(Hệ thống không gian tên do đó, nó có sẵn khá nhiều tự động cho tất cả các chuỗi của chúng tôi.)

5

Dựa trên câu trả lời của Mark ở trên (và Geo của bình luận), tôi đã tạo ra một phiên bản hai lót để loại bỏ tất cả các trường hợp ASCII ngoại lệ từ một chuỗi. Được cung cấp cho những người đang tìm kiếm câu trả lời này (như tôi đã làm).

using System.Text; 

// Create encoder with a replacing encoder fallback 
var encoder = ASCIIEncoding.GetEncoding("us-ascii", 
    new EncoderReplacementFallback(string.Empty), 
    new DecoderExceptionFallback()); 

string cleanString = encoder.GetString(encoder.GetBytes(dirtyString)); 
1

Nếu bạn muốn đại diện 8 bit ký tự được sử dụng trong nhiều mã hóa, điều này có thể giúp bạn.

Bạn phải thay đổi biến số targetEncoding thành bất kỳ mã hóa nào bạn muốn.

Encoding targetEncoding = Encoding.GetEncoding(874); // Your target encoding 
Encoding utf8 = Encoding.UTF8; 

var stringBytes = utf8.GetBytes(Name); 
var stringTargetBytes = Encoding.Convert(utf8, targetEncoding, stringBytes); 
var ascii8BitRepresentAsCsString = Encoding.GetEncoding("Latin1").GetString(stringTargetBytes); 
Các vấn đề liên quan