Giới thiệu
Phương thức String.IsNormalized() trong C# cho biết chuỗi có ở dạng chuẩn hóa Unicode (Unicode normalization form) cụ thể hay không. Chuẩn hóa Unicode đảm bảo các chuỗi tương đương về mặt logic có cùng biểu diễn nhị phân.
Cú pháp
public bool IsNormalized (); public bool IsNormalized (System.Text.NormalizationForm normalizationForm);
- Overload 1: Kiểm tra dạng chuẩn hóa mặc định (Form C - NFC).
- Overload 2: Kiểm tra dạng chuẩn hóa chỉ định (
FormC,FormD,FormKC,FormKD).
Các dạng chuẩn hóa Unicode
| Form | Tên đầy đủ | Mô tả |
|---|---|---|
| FormC (NFC) | Normalization Form Canonical Composition | Kết hợp ký tự tổ hợp thành ký tự đơn (composed). Dùng phổ biến nhất. |
| FormD (NFD) | Normalization Form Canonical Decomposition | Tách ký tự tổ hợp thành ký tự cơ bản + dấu (decomposed). |
| FormKC (NFKC) | Normalization Form Compatibility Composition | Tương thích + kết hợp (ví dụ: ligature "fi" → "fi"). |
| FormKD (NFKD) | Normalization Form Compatibility Decomposition | Tương thích + tách. |
Ví dụ 1: Kiểm tra mặc định (Form C)
using System;
public class Demo {
public static void Main(String[] args) {
string str1 = "Ryan";
string str2 = "Matt";
Console.WriteLine("String 1 = " + str1);
Console.WriteLine("HashCode của String 1 = " + str1.GetHashCode());
Console.WriteLine("Index của 'k' trong str1 = " + str1.IndexOf("k"));
Console.WriteLine("\nString 2 = " + str2);
Console.WriteLine("HashCode của String 2 = " + str2.GetHashCode());
Console.WriteLine("Index của 'k' trong str2 = " + str2.IndexOf("k"));
bool res1 = str1.IsNormalized();
Console.WriteLine("\nstr1 ở dạng chuẩn hóa? = " + res1);
bool res2 = str2.IsNormalized();
Console.WriteLine("str2 ở dạng chuẩn hóa? = " + res2);
}
}
Đầu ra ví dụ 1
String 1 = Ryan HashCode của String 1 = 1580592915 Index của 'k' trong str1 = -1 String 2 = Matt HashCode của String 2 = -1920007383 Index của 'k' trong str2 = -1 str1 ở dạng chuẩn hóa? = True str2 ở dạng chuẩn hóa? = True
Ví dụ 2: Kiểm tra các dạng chuẩn hóa cụ thể
using System;
using System.Text;
public class Demo {
public static void Main(String[] args) {
string str1 = "Imagine Dragons";
string str2 = "Imagine";
Console.WriteLine("String 1 = " + str1);
Console.WriteLine("HashCode của String 1 = " + str1.GetHashCode());
Console.WriteLine("String 2 = " + str2);
Console.WriteLine("HashCode của String 2 = " + str2.GetHashCode());
Console.WriteLine("String 1 bằng String 2: " + str1.Equals(str2));
Console.WriteLine("str1 chuẩn hóa Form C? = " + str1.IsNormalized(NormalizationForm.FormC));
Console.WriteLine("str2 chuẩn hóa Form C? = " + str2.IsNormalized(NormalizationForm.FormC));
Console.WriteLine("str1 chuẩn hóa Form D? = " + str1.IsNormalized(NormalizationForm.FormD));
Console.WriteLine("str2 chuẩn hóa Form D? = " + str2.IsNormalized(NormalizationForm.FormD));
Console.WriteLine("str1 chuẩn hóa Form KC? = " + str1.IsNormalized(NormalizationForm.FormKC));
Console.WriteLine("str2 chuẩn hóa Form KC? = " + str2.IsNormalized(NormalizationForm.FormKC));
Console.WriteLine("str1 chuẩn hóa Form KD? = " + str1.IsNormalized(NormalizationForm.FormKD));
Console.WriteLine("str2 chuẩn hóa Form KD? = " + str2.IsNormalized(NormalizationForm.FormKD));
}
}
Đầu ra ví dụ 2
String 1 = Imagine Dragons HashCode của String 1 = -1546868095 String 2 = Imagine HashCode của String 2 = -1414695254 String 1 bằng String 2: False str1 chuẩn hóa Form C? = True str2 chuẩn hóa Form C? = True str1 chuẩn hóa Form D? = True str2 chuẩn hóa Form D? = True str1 chuẩn hóa Form KC? = True str2 chuẩn hóa Form KC? = True str1 chuẩn hóa Form KD? = True str2 chuẩn hóa Form KD? = True
Ví dụ thực tế: Ký tự có dấu tiếng Việt
using System;
using System.Text;
public class Demo {
public static void Main() {
// "é" có thể là 1 ký tự (U+00E9) hoặc 2 ký tự: 'e' (U+0065) + '´' (U+0301)
string composed = "\u00E9"; // NFC: é (1 char)
string decomposed = "e\u0301"; // NFD: e + combining acute (2 chars)
Console.WriteLine("Composed: " + composed + " Length: " + composed.Length);
Console.WriteLine("Decomposed: " + decomposed + " Length: " + decomposed.Length);
Console.WriteLine("Equals (ordinal): " + composed.Equals(decomposed)); // False
Console.WriteLine("Equals (invariant culture): " + string.Equals(composed, decomposed, StringComparison.InvariantCulture)); // True
Console.WriteLine("Composed IsNormalized(FormC): " + composed.IsNormalized(NormalizationForm.FormC)); // True
Console.WriteLine("Decomposed IsNormalized(FormC): " + decomposed.IsNormalized(NormalizationForm.FormC)); // False
Console.WriteLine("Decomposed IsNormalized(FormD): " + decomposed.IsNormalized(NormalizationForm.FormD)); // True
// Chuẩn hóa về FormC
string normalized = decomposed.Normalize(NormalizationForm.FormC);
Console.WriteLine("Normalized: " + normalized + " Length: " + normalized.Length);
Console.WriteLine("Equals sau normalize: " + composed.Equals(normalized)); // True
}
}
Đầu ra tiếng Việt
Composed: é Length: 1 Decomposed: e´ Length: 2 Equals (ordinal): False Equals (invariant culture): True Composed IsNormalized(FormC): True Decomposed IsNormalized(FormC): False Decomposed IsNormalized(FormD): True Normalized: é Length: 1 Equals sau normalize: True
Khi nào cần chuẩn hóa?
- So sánh chuỗi từ nguồn khác nhau (file, web, input method).
- Lưu trữ database, tìm kiếm, index.
- Bảo mật: chuẩn hóa trước khi hash/mã hóa.
- Xử lý tiếng Việt, tiếng Pháp, tiếng Nhật... có ký tự tổ hợp.