Trường CANON_EQ của lớp Pattern khớp hai ký tự chỉ khi chúng canonically equal (bằng nhau theo chuẩn Unicode). Khi dùng flag này trong compile(), hai ký tự khớp nếu và chỉ nếu full canonical decompositions (phân giải chuẩn đầy đủ) của chúng bằng nhau.
Canonical decomposition là một trong các dạng chuẩn hóa văn bản Unicode (Normalization Form D - NFD).
Ví dụ 1: b + combining dot above (ḃ) vs precomposed ḃ
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CANON_EQ_Example {
public static void main(String args[]) {
String regex = "b\u0307"; // b + combining dot above (U+0307)
Pattern pattern = Pattern.compile(regex, Pattern.CANON_EQ);
Matcher matcher = pattern.matcher("\u1E03"); // ḃ (U+1E03) - precomposed
if (matcher.matches()) {
System.out.println("Tìm thấy khớp");
} else {
System.out.println("Không tìm thấy khớp");
}
}
}
Kết quả
Tìm thấy khớp
Ví dụ 2: a + combining ring above (å) vs các biến thể khác
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CANON_EQ_Example {
public static void main(String args[]) {
String regex = "a\u030A"; // a + combining ring above (U+030A)
Pattern pattern = Pattern.compile(regex, Pattern.CANON_EQ);
String[] input = {
"\u00E5", // å precomposed (U+00E5)
"a\u0311", // a + combining inverted breve (U+0311)
"a\u0325", // a + combining ring below (U+0325)
"a\u030A", // a + combining ring above (U+030A) - giống regex
"a\u1E03", // a + ḃ? (sai)
"a\uFB03" // ligature ffi (U+FB03)
};
for (String ele : input) {
Matcher matcher = pattern.matcher(ele);
if (matcher.matches()) {
System.out.println(ele + " khớp với " + regex);
} else {
System.out.println(ele + " KHÔNG khớp với " + regex);
}
}
}
}
Kết quả
å khớp với å ȃ KHÔNG khớp với å ḁ KHÔNG khớp với å å khớp với å aḃ KHÔNG khớp với å affi KHÔNG khớp với å
Giải thích: Chỉ å (U+00E5) và a\u030A có cùng canonical decomposition (a + ring above), nên khớp. Các combining mark khác không khớp.