Làm thế nào để so sánh các ký tự Unicode “trông giống nhau”?


94

Tôi rơi vào một vấn đề đáng ngạc nhiên.

Tôi đã tải một tệp văn bản trong ứng dụng của mình và tôi có một số logic so sánh giá trị có µ.

Và tôi nhận ra rằng ngay cả khi các văn bản giống nhau thì giá trị so sánh là sai.

 Console.WriteLine("μ".Equals("µ")); // returns false
 Console.WriteLine("µ".Equals("µ")); // return true

Ở dòng sau, ký tự µ được sao chép dán vào.

Tuy nhiên, đây có thể không phải là những ký tự duy nhất như thế này.

Có cách nào trong C # để so sánh các ký tự trông giống nhau nhưng thực sự khác nhau không?


158
Có vẻ như bạn đã tìm thấy mu của Schrödinger.
BoltClock

19
Chúng là các ký tự khác nhau - mặc dù trông giống nhau nhưng chúng có mã ký tự khác nhau.
user2864740

93
Chào mừng bạn đến với Unicode.
ta.speot.is

11
Bạn muốn đạt được những gì? rằng hai người đó phải bằng nhau thì thậm chí mã ký tự của họ khác nhau nhưng cùng một khuôn mặt?
Jade

28
“Trông giống nhau” và “trông giống nhau” là những khái niệm mơ hồ. Chúng có nghĩa là bản sắc của glyphs, hay chỉ là sự giống nhau gần? Gần như thế nào? Lưu ý rằng hai ký tự có thể có các glyph giống hệt nhau ở một số phông chữ, rất giống nhau ở một phông chữ khác và khá giống nhau ở một phông chữ khác. Điều quan trọng là tại sao bạn lại thực hiện một phép so sánh như vậy và trong bối cảnh nào (và khả năng chấp nhận kết quả dương tính giả và âm tính giả).
Jukka K. Korpela 19/1213

Câu trả lời:


125

Trong nhiều trường hợp, bạn có thể chuẩn hóa cả hai ký tự Unicode thành một dạng chuẩn hóa nhất định trước khi so sánh chúng và chúng sẽ có thể khớp với nhau. Tất nhiên, hình thức chuẩn hóa bạn cần sử dụng phụ thuộc vào chính các ký tự; chỉ vì chúng trông giống nhau không nhất thiết có nghĩa là chúng đại diện cho cùng một nhân vật. Bạn cũng cần cân nhắc xem nó có phù hợp với trường hợp sử dụng của mình hay không - xem bình luận của Jukka K. Korpela.

Đối với tình huống cụ thể này, nếu bạn tham khảo các liên kết trong câu trả lời của Tony , bạn sẽ thấy bảng dành cho U + 00B5 cho biết:

Phân rã <compat> CHỮ NHỎ HY LẠP MU (U + 03BC)

Điều này có nghĩa là U + 00B5, ký tự thứ hai trong so sánh ban đầu của bạn, có thể được phân tách thành U + 03BC, ký tự đầu tiên.

Vì vậy, bạn sẽ bình thường hóa các ký tự bằng cách sử dụng phân rã tương thích hoàn toàn, với các dạng chuẩn hóa KC hoặc KD. Đây là một ví dụ nhanh mà tôi đã viết để chứng minh:

using System;
using System.Text;

class Program
{
    static void Main(string[] args)
    {
        char first = 'μ';
        char second = 'µ';

        // Technically you only need to normalize U+00B5 to obtain U+03BC, but
        // if you're unsure which character is which, you can safely normalize both
        string firstNormalized = first.ToString().Normalize(NormalizationForm.FormKD);
        string secondNormalized = second.ToString().Normalize(NormalizationForm.FormKD);

        Console.WriteLine(first.Equals(second));                     // False
        Console.WriteLine(firstNormalized.Equals(secondNormalized)); // True
    }
}

Để biết chi tiết về chuẩn hóa Unicode và các hình thức chuẩn hóa khác nhau, hãy tham khảo System.Text.NormalizationFormthông số kỹ thuật Unicode .


26
Cảm ơn vì liên kết đặc tả Unicode. Lần đầu tiên tôi đọc nó. Lưu ý nhỏ từ nó: "Biểu mẫu chuẩn hóa KC và KD không được áp dụng một cách mù quáng cho văn bản tùy ý. Tốt nhất bạn nên nghĩ về các Biểu mẫu chuẩn hóa này giống như ánh xạ chữ hoa hoặc chữ thường: hữu ích trong một số ngữ cảnh nhất định để xác định ý nghĩa cốt lõi, nhưng cũng hoạt động sửa đổi đối với văn bản có thể không phải lúc nào cũng phù hợp. "
user2864740 19/12/13

149

Bởi vì nó thực sự là các ký hiệu khác nhau ngay cả khi chúng trông giống nhau, đầu tiên là ký tự thực tế và có ký tự code = 956 (0x3BC)và thứ hai là ký tự vi mô và có 181 (0xB5).

Người giới thiệu:

Vì vậy, nếu bạn muốn so sánh chúng và bạn cần chúng bằng nhau, bạn cần phải xử lý thủ công hoặc thay thế một ký tự này bằng một ký tự khác trước khi so sánh. Hoặc sử dụng mã sau:

public void Main()
{
    var s1 = "μ";
    var s2 = "µ";

    Console.WriteLine(s1.Equals(s2));  // false
    Console.WriteLine(RemoveDiacritics(s1).Equals(RemoveDiacritics(s2))); // true 
}

static string RemoveDiacritics(string text) 
{
    var normalizedString = text.Normalize(NormalizationForm.FormKC);
    var stringBuilder = new StringBuilder();

    foreach (var c in normalizedString)
    {
        var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
        if (unicodeCategory != UnicodeCategory.NonSpacingMark)
        {
            stringBuilder.Append(c);
        }
    }

    return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
}

Demo


11
Vì tò mò, lý do gì để có hai ký hiệu µ? Bạn không thấy một chữ K dành riêng với tên "ký hiệu Kilo" (hay bạn nhỉ?).
MartinHaTh 19/1213

12
@MartinHaTh: Theo Wikipedia, đó là "vì lý do lịch sử" .
BoltClock

12
Unicode có rất nhiều ký tự tương thích được mang lại từ các bộ ký tự cũ hơn (như ISO 8859-1 ), để giúp việc chuyển đổi từ các bộ ký tự đó dễ dàng hơn. Trở lại khi các bộ ký tự bị giới hạn ở 8 bit, chúng sẽ bao gồm một vài glyphs (như một số chữ cái Hy Lạp) cho các mục đích sử dụng khoa học và toán học phổ biến nhất. Việc tái sử dụng glyph dựa trên ngoại hình là phổ biến, vì vậy không có chữ 'K' chuyên biệt nào được thêm vào. Nhưng đó luôn là một cách giải quyết; biểu tượng chính xác cho "micro" là mu viết thường trong tiếng Hy Lạp, ký hiệu chính xác cho Ohm là omega viết hoa thực tế, v.v.
VGR

8
Không có gì tốt hơn so với khi một cái gì đó được thực hiện cho nho khô cuồng loạn
paulm

11
Có K đặc biệt cho ngũ cốc không?

86

Cả hai đều có mã ký tự khác nhau: Tham khảo phần này để biết thêm chi tiết

Console.WriteLine((int)'μ');  //956
Console.WriteLine((int)'µ');  //181

Trong đó, đầu tiên là:

Display     Friendly Code   Decimal Code    Hex Code    Description
====================================================================
μ           &mu;            &#956;          &#x3BC;     Lowercase Mu
µ           &micro;         &#181;          &#xB5;      micro sign Mu

Hình ảnh


39

Đối với ví dụ cụ thể của μ(mu) và µ(dấu hiệu vi mô), cái sau có sự phân tách khả năng tương thích với cái trước, vì vậy bạn có thể chuẩn hóa chuỗi thành FormKChoặcFormKD chuyển đổi các dấu hiệu vi mô thành mus.

Tuy nhiên, có rất nhiều bộ ký tự trông giống nhau nhưng không tương đương với bất kỳ hình thức chuẩn hóa Unicode nào. Ví dụ: A(Latinh), Α(Hy Lạp) và А(Cyrillic). Trang web Unicode có tệp confusables.txt với danh sách các tệp này, nhằm giúp các nhà phát triển đề phòng các cuộc tấn công đồng nhất . Nếu cần, bạn có thể phân tích cú pháp tệp này và xây dựng một bảng để "chuẩn hóa trực quan" các chuỗi.


Chắc chắn cần biết khi sử dụng Normalize. Có vẻ như đáng ngạc nhiên là chúng vẫn khác biệt.
user2864740

4
@ user2864740: Nếu chữ tau Hy Lạp viết hoa không khác biệt với chữ T La Mã, sẽ rất khó để phân loại văn bản Hy Lạp và La Mã một cách hợp lý theo thứ tự bảng chữ cái. Hơn nữa, nếu một kiểu chữ sử dụng một phong cách trực quan khác cho các chữ cái Hy Lạp và La Mã, sẽ rất mất tập trung nếu các chữ cái Hy Lạp có hình dạng giống chữ La Mã được hiển thị khác với những chữ cái không.
supercat 19/1213

7
Quan trọng hơn, việc thống nhất các bảng chữ cái châu Âu sẽ gây ra ToUpper/ ToLowerkhó thực hiện. Bạn sẽ cần phải có "B".ToLower()được bbằng tiếng Anh nhưng βtrong tiếng Hy Lạp và вtiếng Nga. Vì hiện tại, chỉ có tiếng Thổ Nhĩ Kỳ (không có dấu chấm i) và một vài ngôn ngữ khác cần các quy tắc viết hoa khác với quy tắc mặc định.
dan04 19/12/13

@ dan04: Không biết có ai từng cân nhắc việc gán điểm mã duy nhất cho cả 4 biến thể của chữ "i" và "I" trong tiếng Thổ Nhĩ Kỳ không? Điều đó sẽ loại bỏ bất kỳ sự mơ hồ nào trong hành vi của toUpper / toLower.
supercat

34

Tìm kiếm cả hai ký tự trong cơ sở dữ liệu Unicode và xem sự khác biệt .

Một là Chữ cái nhỏ trong tiếng Hy Lạpµ và một là Ký hiệu Vi mô µ .

Name            : MICRO SIGN
Block           : Latin-1 Supplement
Category        : Letter, Lowercase [Ll]
Combine         : 0
BIDI            : Left-to-Right [L]
Decomposition   : <compat> GREEK SMALL LETTER MU (U+03BC)
Mirror          : N
Index entries   : MICRO SIGN
Upper case      : U+039C
Title case      : U+039C
Version         : Unicode 1.1.0 (June, 1993)

Name            : GREEK SMALL LETTER MU
Block           : Greek and Coptic
Category        : Letter, Lowercase [Ll]
Combine         : 0
BIDI            : Left-to-Right [L]
Mirror          : N
Upper case      : U+039C
Title case      : U+039C
See Also        : micro sign U+00B5
Version         : Unicode 1.1.0 (June, 1993)

4
Làm thế nào mà điều này lại nhận được 37 phiếu ủng hộ? Nó không trả lời câu hỏi ("Làm thế nào để so sánh các ký tự unicode"), nó chỉ nhận xét tại sao ví dụ cụ thể này không bằng nhau. Tốt nhất, nó nên là một bình luận về câu hỏi. Tôi hiểu các tùy chọn định dạng nhận xét không cho phép đăng nó độc đáo như các tùy chọn định dạng câu trả lời, nhưng đó không phải là lý do hợp lệ để đăng dưới dạng câu trả lời.
Konerak

5
Thực ra câu hỏi là một câu hỏi khác, hỏi tại sao kiểm tra bình đẳng μ và µ lại trả về false. Câu trả lời này trả lời nó. Sau đó OP hỏi một câu hỏi khác (câu hỏi này) làm thế nào để so sánh hai nhân vật trông giống nhau. Cả hai câu hỏi đều có câu trả lời hay nhất và sau đó một trong những người kiểm duyệt đã hợp nhất cả hai câu hỏi để chọn câu trả lời tốt nhất của câu thứ hai là tốt nhất. Có người thay đổi nội dung câu hỏi này, vì vậy mà nó sẽ tóm tắt
Subin Jacob

Thực ra, tôi không thêm bất kỳ nội dung sau khi hợp nhất
Subin Jacob

24

CHỈNH SỬA Sau khi kết hợp câu hỏi này với Cách so sánh 'μ' và 'µ' trong C #
Câu trả lời gốc được đăng:

 "μ".ToUpper().Equals("µ".ToUpper()); //This always return true.

CHỈNH SỬA Sau khi đọc các nhận xét, có, không tốt nếu sử dụng phương pháp trên vì nó có thể cung cấp kết quả sai cho một số loại đầu vào khác, đối với điều này, chúng ta nên sử dụng bình thường hóa bằng cách sử dụng phân rã tương thích hoàn toàn như đã đề cập trong wiki . (Cảm ơn câu trả lời được đăng bởi BoltClock )

    static string GREEK_SMALL_LETTER_MU = new String(new char[] { '\u03BC' });
    static string MICRO_SIGN = new String(new char[] { '\u00B5' });

    public static void Main()
    {
        string Mus = "µμ";
        string NormalizedString = null;
        int i = 0;
        do
        {
            string OriginalUnicodeString = Mus[i].ToString();
            if (OriginalUnicodeString.Equals(GREEK_SMALL_LETTER_MU))
                Console.WriteLine(" INFORMATIO ABOUT GREEK_SMALL_LETTER_MU");
            else if (OriginalUnicodeString.Equals(MICRO_SIGN))
                Console.WriteLine(" INFORMATIO ABOUT MICRO_SIGN");

            Console.WriteLine();
            ShowHexaDecimal(OriginalUnicodeString);                
            Console.WriteLine("Unicode character category " + CharUnicodeInfo.GetUnicodeCategory(Mus[i]));

            NormalizedString = OriginalUnicodeString.Normalize(NormalizationForm.FormC);
            Console.Write("Form C Normalized: ");
            ShowHexaDecimal(NormalizedString);               

            NormalizedString = OriginalUnicodeString.Normalize(NormalizationForm.FormD);
            Console.Write("Form D Normalized: ");
            ShowHexaDecimal(NormalizedString);               

            NormalizedString = OriginalUnicodeString.Normalize(NormalizationForm.FormKC);
            Console.Write("Form KC Normalized: ");
            ShowHexaDecimal(NormalizedString);                

            NormalizedString = OriginalUnicodeString.Normalize(NormalizationForm.FormKD);
            Console.Write("Form KD Normalized: ");
            ShowHexaDecimal(NormalizedString);                
            Console.WriteLine("_______________________________________________________________");
            i++;
        } while (i < 2);
        Console.ReadLine();
    }

    private static void ShowHexaDecimal(string UnicodeString)
    {
        Console.Write("Hexa-Decimal Characters of " + UnicodeString + "  are ");
        foreach (short x in UnicodeString.ToCharArray())
        {
            Console.Write("{0:X4} ", x);
        }
        Console.WriteLine();
    }

Đầu ra

INFORMATIO ABOUT MICRO_SIGN    
Hexa-Decimal Characters of µ  are 00B5
Unicode character category LowercaseLetter
Form C Normalized: Hexa-Decimal Characters of µ  are 00B5
Form D Normalized: Hexa-Decimal Characters of µ  are 00B5
Form KC Normalized: Hexa-Decimal Characters of µ  are 03BC
Form KD Normalized: Hexa-Decimal Characters of µ  are 03BC
 ________________________________________________________________
 INFORMATIO ABOUT GREEK_SMALL_LETTER_MU    
Hexa-Decimal Characters of µ  are 03BC
Unicode character category LowercaseLetter
Form C Normalized: Hexa-Decimal Characters of µ  are 03BC
Form D Normalized: Hexa-Decimal Characters of µ  are 03BC
Form KC Normalized: Hexa-Decimal Characters of µ  are 03BC
Form KD Normalized: Hexa-Decimal Characters of µ  are 03BC
 ________________________________________________________________

Trong khi đọc thông tin bằng Unicode_equivalence, tôi đã tìm thấy

Việc lựa chọn tiêu chí tương đương có thể ảnh hưởng đến kết quả tìm kiếm. Ví dụ: một số chữ ghép kiểu chữ như U + FB03 (ffi), ..... vì vậy tìm kiếm U + 0066 (f) làm chuỗi con sẽ thành công trong chuẩn hóa NFKC của U + FB03 nhưng không thành công trong chuẩn hóa NFC của U + FB03.

Vì vậy, để so sánh sự tương đương, thông thường chúng ta nên sử dụng FormKCtức là chuẩn hóa NFKC hoặc FormKDtức là chuẩn hóa NFKD.
Tôi hơi tò mò muốn biết thêm về tất cả các ký tự Unicode nên tôi đã tạo mẫu sẽ lặp lại trên tất cả các ký tự Unicode trong đó UTF-16và tôi nhận được một số kết quả mà tôi muốn thảo luận

  • Thông tin về các ký tự có giá trị FormCFormDgiá trị chuẩn hóa không tương đương
    Total: 12,118
    Character (int value): 192-197, 199-207, 209-214, 217-221, 224-253, ..... 44032-55203
  • Thông tin về các ký tự có giá trị FormKCFormKDgiá trị chuẩn hóa không tương đương
    Total: 12,245
    Character (int value): 192-197, 199-207, 209-214, 217-221, 224-228, ..... 44032-55203, 64420-64421, 64432-64433, 64490-64507, 64512-64516, 64612-64617, 64663-64667, 64735-64736, 65153-65164, 65269-65274
  • Tất cả ký tự có giá trị FormCFormDgiá trị chuẩn hóa không tương đương, ở đó FormKCFormKDgiá trị chuẩn hóa cũng không tương đương ngoại trừ các ký tự này Các ký
    tự:901 '΅', 8129 '῁', 8141 '῍', 8142 '῎', 8143 '῏', 8157 '῝', 8158 '῞'
    , 8159 '῟', 8173 '῭', 8174 '΅'
  • Ký tự phụ có giá trị FormKCFormKDgiá trị chuẩn hóa không tương đương, nhưng ở đó FormCFormDgiá trị chuẩn hóa là tương đương
    Total: 119
    Các ký tự:452 'DŽ' 453 'Dž' 454 'dž' 12814 '㈎' 12815 '㈏' 12816 '㈐' 12817 '㈑' 12818 '㈒' 12819 '㈓' 12820 '㈔' 12821 '㈕', 12822 '㈖' 12823 '㈗' 12824 '㈘' 12825 '㈙' 12826 '㈚' 12827 '㈛' 12828 '㈜' 12829 '㈝' 12830 '㈞' 12910 '㉮' 12911 '㉯' 12912 '㉰' 12913 '㉱' 12914 '㉲' 12915 '㉳' 12916 '㉴' 12917 '㉵' 12918 '㉶' 12919 '㉷' 12920 '㉸' 12921 '㉹' 12922 '㉺' 12923 '㉻' 12924 '㉼' 12925 '㉽' 12926 '㉾' 13056 '㌀' 13058 '㌂' 13060 '㌄' 13063 '㌇' 13070 '㌎' 13071 '㌏' 13072 '㌐' 13073 '㌑' 13075 '㌓' 13077 '㌕' 13080 '㌘' 13081 '㌙' 13082 '㌚' 13086 '㌞' 13089 '㌡' 13092 '㌤' 13093 '㌥' 13094 '㌦' 13099 '㌫' 13100 '㌬' 13101 '㌭' 13102 '㌮' 13103 '㌯' 13104 '㌰' 13105 '㌱' 13106 '㌲' 13108 '㌴' 13111 '㌷' 13112 '㌸' 13114 '㌺' 13115 '㌻' 13116 '㌼' 13117 '㌽' 13118 '㌾' 13120 '㍀' 13130 '㍊' 13131 '㍋' 13132 '㍌' 13134 '㍎' 13139 '㍓' 13140 '㍔' 13142 '㍖' .......... ﺋ' 65164 'ﺌ' 65269 'ﻵ' 65270 'ﻶ' 65271 'ﻷ' 65272 'ﻸ' 65273 'ﻹ' 65274'
  • Có một số ký tự không thể được chuẩn hóa , họ sẽ ném ArgumentExceptionnếu cố gắng
    Total:2081 Characters(int value): 55296-57343, 64976-65007, 65534

Các liên kết này có thể thực sự hữu ích để hiểu những quy tắc nào chi phối sự tương đương của Unicode

  1. Unicode_equivalence
  2. Unicode_compatibility_characters

4
Kỳ lạ nhưng hoạt động ... Ý tôi là chúng là hai ký tự khác nhau với ý nghĩa khác nhau và chuyển đổi chúng thành chữ trên làm cho chúng bằng nhau? Tôi không thấy logic nhưng thoải mái giải pháp 1
BudBrot

45
Giải pháp này che dấu sự cố và có thể gây ra sự cố trong một trường hợp chung. Loại thử nghiệm này sẽ tìm thấy điều đó "m".ToUpper().Equals("µ".ToUpper());"M".ToUpper().Equals("µ".ToUpper());cũng đúng. Điều này có thể không được mong muốn.
Andrew Leach

6
-1 - đây là một ý tưởng khủng khiếp. Không làm việc với Unicode như thế này.
Konrad Rudolph

1
Thay vì các thủ thuật dựa trên ToUpper (), tại sao không sử dụng String.Equals ("μ", "μ", StringComparison.CurrentCultureIgnoreCase)?
svenv 19/1213

6
Có một lý do chính đáng để phân biệt giữa "MICRO SIGN" và "GREEK SMALL CHỮ MU" - để nói rằng "chữ hoa" của dấu hiệu vi mô vẫn là dấu hiệu vi mô. Nhưng viết hoa thay đổi vi mô thành lớn, kỹ thuật hạnh phúc.
Greg

9

Rất có thể, có hai mã ký tự khác nhau tạo nên (rõ ràng) cùng một ký tự. Mặc dù về mặt kỹ thuật không bằng nhau, nhưng chúng trông giống nhau. Hãy xem bảng ký tự và xem liệu có nhiều trường hợp của ký tự đó không. Hoặc in ra mã ký tự của hai ký tự trong mã của bạn.


6

Bạn hỏi "làm thế nào để so sánh chúng" nhưng bạn không cho chúng tôi biết bạn muốn làm gì.

Có ít nhất hai cách chính để so sánh chúng:

Hoặc bạn so sánh chúng trực tiếp với bạn và chúng khác nhau

Hoặc bạn sử dụng Chuẩn hóa tương thích Unicode nếu nhu cầu của bạn là so sánh để thấy chúng khớp với nhau.

Tuy nhiên, có thể có vấn đề vì chuẩn hóa tương thích Unicode sẽ làm cho nhiều ký tự khác so sánh bằng nhau. Nếu bạn chỉ muốn hai ký tự này được coi là giống nhau, bạn nên sử dụng các hàm chuẩn hóa hoặc so sánh của riêng mình.

Để có giải pháp cụ thể hơn, chúng tôi cần biết vấn đề cụ thể của bạn. Bối cảnh mà bạn gặp phải vấn đề này là gì?


1
"Dấu hiệu vi mô" và ký tự mu viết thường có tương đương nhau về mặt kinh điển không? Sử dụng chuẩn hóa chuẩn sẽ cung cấp cho bạn một so sánh chặt chẽ hơn.
Tanner Swett 19/1213

@ TannerL.Swett: Thực ra tôi thậm chí không chắc chắn làm thế nào để kiểm tra xem ra khỏi đỉnh đầu của tôi ...
hippietrail

1
Trên thực tế, tôi đang nhập một tệp có công thức vật lý. Bạn đã đúng về chuẩn hóa. Tôi phải trải qua nó một cách sâu sắc hơn ..
DJ

Loại tệp nào? Một cái gì đó được làm bằng tay bằng văn bản Unicode thuần túy bởi một người? Hoặc thứ gì đó xuất ra bởi một ứng dụng ở một định dạng cụ thể?
hippietrail

5

Nếu tôi muốn nói đúng, tôi sẽ nói rằng câu hỏi của bạn không có ý nghĩa, nhưng vì chúng ta đang đến gần lễ Giáng sinh và những con chim đang hót, tôi sẽ tiếp tục điều này.

Trước hết, 2 thực thể mà bạn đang cố gắng so sánh là glyphs, một glyph là một phần của tập hợp các glyph được cung cấp bởi cái thường được gọi là "phông chữ", cái thường đi kèm với ttf,otf hoặc bất cứ tập tin định dạng bạn đang sử dụng.

Các glyph là đại diện của một biểu tượng nhất định và vì chúng là biểu diễn phụ thuộc vào một tập hợp cụ thể, bạn không thể mong đợi có 2 biểu tượng giống nhau hoặc thậm chí "tốt hơn", đó là một cụm từ không có ý nghĩa nếu bạn xem xét bối cảnh, ít nhất bạn nên chỉ định phông chữ hoặc bộ glyphs bạn đang xem xét khi bạn tạo một câu hỏi như thế này.

Những gì thường được sử dụng để giải quyết một vấn đề tương tự như vấn đề mà bạn đang gặp phải, đó là OCR, về cơ bản là một phần mềm nhận dạng và so sánh các glyph, Nếu C # cung cấp OCR theo mặc định, tôi không biết điều đó, nhưng nói chung nó thực sự rất tệ ý tưởng nếu bạn không thực sự cần OCR và bạn biết phải làm gì với nó.

Bạn có thể kết thúc việc hiểu một cuốn sách vật lý như một cuốn sách cổ của Hy Lạp mà không đề cập đến thực tế rằng OCR nói chung là đắt về mặt tài nguyên.

Có một lý do tại sao những ký tự đó được bản địa hóa theo cách chúng được bản địa hóa, chỉ là đừng làm vậy.


1

Có thể vẽ cả hai ký tự với cùng kiểu phông chữ và kích thước bằng DrawStringphương thức. Sau khi hai ảnh bitmap có ký hiệu đã được tạo, có thể so sánh chúng theo từng pixel.

Lợi thế của phương pháp này là bạn có thể so sánh không chỉ các biểu đồ tuyệt đối bằng nhau mà còn tương tự (với dung sai xác định).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.