2011-06-22 101 views
6

Như đã nói trong dòng tiêu đề, tôi muốn chuyển đổi các ký tự zenkaku thành hankaku và ngược vrsa trong C#, nhưng không thể tìm ra cách thực hiện. Vì vậy, hãy nói "ラ ー メ ン" với "ラ ー メ ン" và cách khác. Có thể viết điều này trong một phương pháp xác định tự động theo cách chuyển đổi cần phải đi, dựa trên định dạng của đầu vào?Chuyển đổi các ký tự zenkaku thành hankaku và ngược lại trong C#

Trả lời

2

Bạn có thể sử dụng phương pháp Strings.StrConv() bằng cách bao gồm một tham chiếu đến Microsoft.VisualBasic.dll, hoặc bạn có thể p/gọi LCMapString() chức năng có nguồn gốc:

private const uint LOCALE_SYSTEM_DEFAULT = 0x0800; 
private const uint LCMAP_HALFWIDTH = 0x00400000; 

public static string ToHalfWidth(string fullWidth) 
{ 
    StringBuilder sb = new StringBuilder(256); 
    LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_HALFWIDTH, fullWidth, -1, sb, sb.Capacity); 
    return sb.ToString(); 
} 

[DllImport("kernel32.dll", CharSet = CharSet.Unicode)] 
private static extern int LCMapString(uint Locale, uint dwMapFlags, string lpSrcStr, int cchSrc, StringBuilder lpDestStr, int cchDest); 

và bạn có thể cũng làm ngược lại:

private const uint LCMAP_FULLWIDTH = 0x00800000; 

public static string ToFullWidth(string halfWidth) 
{ 
    StringBuilder sb = new StringBuilder(256); 
    LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_FULLWIDTH, halfWidth, -1, sb, sb.Capacity); 
    return sb.ToString(); 
} 

Để phát hiện định dạng của chuỗi đầu vào, tôi không biết một cách dễ dàng mà không thực hiện chuyển đổi trước tiên và so sánh kết quả. (Điều gì sẽ xảy ra nếu chuỗi chứa cả các ký tự có độ rộng đầy đủ và nửa chiều rộng?)

+0

Cảm ơn bạn đã đề xuất. Điều này về cơ bản trả lời câu hỏi của tôi. Một điều đáng tiếc là không có cách nào dễ dàng để kết hợp hai hàm để chuyển đổi được thực hiện tự động. –

+0

Làm như vậy sẽ là hành vi mơ hồ. Nếu tôi đưa ra "ラ ー メ ン" (chú ý char đầu tiên là nửa chiều rộng) làm đầu vào cho hàm kết hợp của bạn, bạn có xuất ra "ラ ー メ ン" (chuyển đổi char-by-char), "ラ ー メ ン" (chuyển đổi dựa trên char đầu tiên) hay "ラ ー メ ン "(chuyển đổi dựa trên đa số)? –

+0

Bạn hoàn toàn đúng, nó khá phức tạp ... Tôi đang làm điều này để làm nổi bật các chất nền trong một chuỗi ký tự chứa các ký tự tiếng Nhật. Tôi đoán trong trường hợp này bao gồm tất cả các khả năng sẽ mất quá nhiều sức mạnh xử lý vì không có nhiều lợi ích cho người dùng cuối. Tôi đã làm những gì bạn đề nghị bằng cách này, chuyển đổi thành zenkaku và hankaku và sau đó so sánh cả hai để xem liệu có bất cứ điều gì xảy ra hay không, vì vậy tôi có thể loại bỏ kanji. Cảm ơn đã giúp đỡ! –

1

Một cách tiếp cận là biên soạn danh sách tất cả các ký tự bạn muốn chuyển đổi và cách chúng ánh xạ với nhau, sau đó lặp lại chuỗi đầu vào và thay thế tất cả các ký tự trong danh sách tương đương.

var fullToHalf = new Dictionary<char, char> 
{ 
    ... 
    { '\u30E9', '\uFF97' }, // KATAKANA LETTER RA -> HALFWIDTH KATAKANA LETTER RA 
    { '\u30EA', '\uFF98' }, // KATAKANA LETTER RI -> HALFWIDTH KATAKANA LETTER RI 
    ... 
}; 

var halfToFull = fullToHalf.ToDictionary(kv => kv.Value, kv => kv.Key); 

var input = "\u30E9"; 

var isFullWidth = input.All(ch => fullToHalf.ContainsKey(ch)); 
var isHalfWidth = input.All(ch => halfToFull.ContainsKey(ch)); 

var result = new string(input.Select(ch => fullToHalf[ch]).ToArray()); 
// result == "\uFF97" 

Unicode Chart: Halfwidth and Fullwidth Forms (FF00-FFEF)

+0

Cảm ơn đề xuất. Tôi nghĩ về một cái gì đó như thế này với một chuỗi.Contains và mảng chứa tất cả các nhân vật, nhưng tôi tự hỏi về thời gian đó sẽ mất. Một từ điển có vẻ neater vì vậy tôi có thể cung cấp cho điều này một đi. –

+0

Chỉ cần nói: cảm ơn rất nhiều vì gợi ý. Tôi thích cách tiếp cận này, nhưng nó quá phức tạp đối với những gì tôi đang cố gắng đạt được. Ngoài ra một vấn đề tiềm năng tôi có với điều này là cần phải tạo ra các từ điển trước ... Một chút lạ rằng đây nên là cách duy nhất để làm điều này trong C# tinh khiết khi VB có phương pháp StrConv(). –

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