التعامل مع النصوص التي تحتوي على علامات التشكيل
بعض اللغات مثل العربية والعبرية تسمح لك بإضافة بعض العلامات على الأحرف مثل علامات الإعراب في اللغة العربية (ضمة، كسرة، إلخ)
وتسمى هذه العلامات Combining Characters أم الحروف الأساسية والتي تقوم هذه العلامات بالدخول عليها فتسمى Base Characters.
وذلك لأن هذه العلامات ليست في أصلها حرفا ولا تأخذ شكل حرف بل هي إضافة/علامة على الحرف الأساسي.
مثال:
ت دخل عليها علامة الضمة ُ فأصبحت تُ
ت دخل عليه علامتين شدة ّ وفتحتين ً فأصبحت تًّ
فنجد أنه عندما دمجت Combine علامة مع حرف أصبحت حرف واحد ولكنه بحرفين (علامة + حرف) وفي المثال التاني دمجنا علامتين + حرف بأصبحت 3 أحرف في حرف واحد
تعديد Enumerating نص
في سي شارب -أو في البرمجة عامة- كيف نقوم بتعديد Enumerating النص المكون من هذه الأحرف؟
سنأخذ مثال لفظ مُـحمَّـد فهو مكون من 9 حروف:
1. ميم 2. ضمة 3. كشيدة 4. حاء 5. ميم 6. شدة 7. فتحة 8. كشيدة 9. دال
ولكن بعد دمج أحرفه نجد أنه أصبح 6 فقط:
1. ميم مضمومة 2. كشيدة 3. حاء 4. ميم عليها شدة وفتحة 5. كشيدة 6. دال
في المثال التالي نقوم بتعديد حروف هذا النص:
string someName = "مُـحمَّـد";
for (int i = 0; i < someName.Length; i++)
MessageBox.Show(string.Format("{0}\t{1}", i, someName));سنجد أنه في المثال تم إظاهر 9 أحرف وليس 6 بعد الدمج Combining.
ما الحل؟
استخدام الكلاس System.Globalization.StringInfo في التعديد Enumerating
الحل باستخدام الكلاس System.Globalization.StringInfo.
تحتوي هذه الكلاس على الدالة GetTextElementEnumerator والتي تقوم بإرجاع كلاس أخرى من نوع System.Globalization.TextElementEnumerator والتي تستخدم لعمل Enumerating على النص. لاحظ الكود:
string someName = "مُـحمَّـد";
System.Globalization.TextElementEnumerator enumerator =
System.Globalization.StringInfo.GetTextElementEnumerator(someName);
while (enumerator.MoveNext())
MessageBox.Show(string.Format("{0}\t{1}", enumerator.ElementIndex, enumerator.Current));سنلاحظ أنه تم إرجاع 6 أحرف فقط أي أنه تم دمج العلامات مع الأحرف ولكن لاحظ أن Index الأحرف ثابت.
المقارنة بين نص فيه علامات Combining Characters والآخر لا
وهنا يظهر سؤال آخر! كيف يتم المقارنة بين نصين مثل "محمد" و "مُـحمًّـد"؟؟؟
الأمر ليس بسيط فبداية طول النص الأول 4 وأما النص الثاني ف 9!!! حتى بعد الدمج أصبح 6 -لاحظ أنه هناك كشيدتين-.
والحل هنا هو استخدام أحد الـ Overloads الخاصة بـ System.String.Compare:
string withCombiningChars = "مُـحمَّـد";
string withoutCombiningChars = "محمد";
Console.WriteLine(
string.Compare(withCombiningChars, withoutCombiningChars)
== 0 ? "Both strings are the same." : "The strings are different!");
if (string.Compare(withCombiningChars, withoutCombiningChars,
System.Threading.Thread.CurrentThread.CurrentCulture,
System.Globalization.CompareOptions.IgnoreSymbols) == 0)
Console.WriteLine("Both strings are the same.");
else
Console.WriteLine("The strings are different!");لاحظ أنه باستخدام الاختيار CompareOptions.IgnoreSymbols تم استبعاد العلامات وكذلك الكشيدة من المقارنة بين النصين فبذلك أصبحا متساويين.
معلومة: الكشيدة ليست من الحروف العربية.
استخدام برنامج Character Map
باستخدام أحد البرامج مثل برنامج Character Map يمكنك مشاهدة الحروف والعلامات التي تستطيع كتابتها بخط معين.
لتشغيل البرنامج:
اكتب CharMap.exe في Run. أو افتح Start->Programs->Accessories->System Tools->Character Map.
كتابة العلامات في اللغة العربية
ً الفتحتان باستخدام Shift+W الكود: 0x064B
ٌ الضمتان باستخدام Shift+R الكود: 0x064C
ٍ الكسرتان باستخدام Shift+S الكود: 0x064D
َ الفتحة باستخدام Shift+Q الكود: 0x064E
ُ الضمة باستخدام Shift+E الكود: 0x064F
ِ الكسرة باستخدام Shift+A الكود: 0x0650
ّ الشدة باستخدام Shift+~ الكود: 0x0651
ْ السكون باستخدام Shift+X الكود: 0x0652
هذا الدرس مترجم من موقع:
http://m-elsheimy.spaces.live.com/blog/cns!CACC2893AA2E5E66!584.entry