4. فئات .NET شائعة الاستخدام
نقدم هنا بعض الفئات المهمة في منصة .NET، حتى للمبتدئين. سنوضح أولاً كيفية الحصول على معلومات حول مئات الفئات المتاحة.
4.1. طلب المساعدة باستخدام SDK.NET
4.1.1. wincv
إذا تم تثبيت SDK فقط دون Visual Studio.NET، فيمكن استخدام برنامج wincv.exe الموجود عادةً في هيكل مجلدات SDK، على سبيل المثال C:\Program Files\Microsoft Visual Studio.NET 2003\SDK\v1.1. عند تشغيل هذه الأداة المساعدة، تظهر الواجهة التالية:
![]() |
نكتب في (1) اسم الفئة المطلوبة. ويؤدي ذلك إلى عرض (2) مجموعة متنوعة من السمات الممكنة. نختار السمة المناسبة ونحصل على النتيجة في (3)، وهي هنا الفئة HashTable. هذه الطريقة مناسبة إذا كنا نعرف اسم الفئة التي نبحث عنها. إذا أردنا استكشاف قائمة الخيارات التي توفرها منصة .NET، فيمكن استخدام الملف HTML StartHere.htm الموجود أيضًا مباشرةً في مجلد تثبيت SSK.Net، على سبيل المثال C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.

الرابط .NET Framework SDK Documentation هو الرابط الذي يجب اتباعه للحصول على نظرة عامة على الفئات .NET:

هنا، سنقوم باتباع الرابط [Bibliothèque de classes]. نجد فيه قائمة بجميع فئات .NET:

لننتقل على سبيل المثال إلى الرابط System.Collections. تضم مساحة الأسماء هذه فئات متنوعة تُنفذ مجموعات، ومن بينها الفئة HashTable:

لنتبع الرابط HashTable أدناه:

نحصل على الصفحة التالية:

نلاحظ أدناه موضع المؤشر. فهو يشير إلى رابط يتيح تحديد اللغة المطلوبة، وهي في هذه الحالة Visual Basic.
نجد فيه النموذج الأولي للفئة بالإضافة إلى أمثلة على استخدامها. لننتقل إلى الرابط [Hashtable, membres] أدناه:

نحصل على الوصف الكامل للفئة:

هذه الطريقة هي الأفضل لاكتشاف SDK وفئاتها. تُثبت أداة WinCV فائدتها عندما يكون لدى المستخدم معرفة مسبقة بسيطة بالفئة، ولكنه نسي بعض عناصرها. عندئذٍ تتيح أداة WinCV العثور بسرعة على الفئة وعناصرها.
4.2. البحث عن المساعدة بشأن الفئات باستخدام VS.NET
نقدم هنا بعض الإرشادات للحصول على المساعدة باستخدام Visual Studio.NET
4.2.1. خيار «المساعدة»
لنختر الخيار [?] من القائمة.

ستظهر النافذة التالية:

في القائمة المنسدلة، يمكننا اختيار مرشح المساعدة. هنا، سنختار المرشح [Visual Basic].

هناك نوعان من المساعدة المفيدة:
- دليل لغة VB.NET نفسها (قواعد اللغة)
- المساعدة الخاصة بـ classes.NET التي يمكن استخدامها مع لغة VB.NET
يمكن الوصول إلى دليل لغة VB.NET عبر [Visual Studio.NET/Visual Basic et Visual C#/Reference/Visual Basic]:

تظهر صفحة المساعدة التالية:

ومن هناك، تتيح لنا الأقسام الفرعية المختلفة الحصول على المساعدة حول مواضيع مختلفة في VB.NET. وسنولي اهتمامًا خاصًا للدروس التعليمية في VB.NET:

للوصول إلى الفئات المختلفة لمنصة .NET، سنختار المساعدة [Visual Studio.NET/.NET Framework].

سنركز بشكل خاص على القسم [Référence/Bibliothèque de classes]:

لنفترض أننا مهتمون بالفئة [ArrayList]. وهي موجودة في مساحة الأسماء [System.Collections]. يجب معرفة ذلك، وإلا فسيكون من الأفضل استخدام طريقة البحث الموضحة أدناه. نحصل على المساعدة التالية:

يقدم الرابط [ArrayList, classe] نظرة عامة على الفئة:

يوجد هذا النوع من الصفحات لجميع الفئات. وهي تقدم ملخصًا عن الفئة مع أمثلة. وللحصول على وصف لأعضاء الفئة، يمكن اتباع الرابط [ArrayList, membres]:

4.2.2. المساعدة/الفهرس

يتيح الخيار [Aide/index] البحث عن مساعدة أكثر تحديدًا من المساعدة السابقة. ما عليك سوى كتابة الكلمة المفتاحية التي تبحث عنها:

ميزة هذه الطريقة مقارنة بالطريقة السابقة هي أنه لا داعي لمعرفة مكان ما تبحث عنه في نظام المساعدة. وربما تكون هذه هي الطريقة المفضلة عند إجراء بحث محدد، في حين أن الطريقة الأخرى أكثر ملاءمة لاكتشاف كل ما تقدمه المساعدة.
4.3. فئة String
تحتوي فئة String على العديد من الخصائص والأساليب. وفيما يلي بعض منها:
عدد أحرف السلسلة | |
خاصية مفهرسة افتراضيًا. [String].Chars(i) هو الحرف رقم i في السلسلة | |
تُرجع القيمة «صحيح» إذا كانت السلسلة تنتهي بالقيمة | |
تُرجع القيمة "صحيح" إذا كانت السلسلة تبدأ بالقيمة | |
تُرجع القيمة "صحيح" إذا كانت السلسلة تساوي value | |
تُرجع الموضع الأول للسلسلة «value» في السلسلة - يبدأ البحث من الحرف رقم 0 | |
يعرض الموضع الأول في السلسلة من السلسلة value - يبدأ البحث من الحرف رقم startIndex | |
طريقة الفئة - تُرجع سلسلة أحرف، وهي نتيجة ربط قيم المصفوفة value باستخدام الفاصل separator | |
تُرجع سلسلة نصية هي نسخة من السلسلة الحالية حيث تم استبدال الحرف oldChar بالحرف newChar | |
يُنظر إلى السلسلة على أنها سلسلة من الحقول مفصولة بالأحرف الموجودة في المصفوفة separator. والنتيجة هي مصفوفة من هذه الحقول | |
سلسلة فرعية من السلسلة الحالية تبدأ من الموضع startIndex وتحتوي على length حرفًا | |
تحويل السلسلة الحالية إلى أحرف صغيرة | |
تحويل السلسلة الحالية إلى أحرف كبيرة | |
يزيل المسافات في بداية ونهاية السلسلة الحالية |
يمكن اعتبار السلسلة C مصفوفة من الأحرف. وبالتالي
- C.Chars(i) هو الحرف i من C
- C.Length هو عدد أحرف C
لنأخذ المثال التالي:
' خيارات
Option Strict On
Option Explicit On
' مساحات الأسماء
Imports System
Module test
Sub Main()
Dim uneChaine As String = "l'oiseau vole au-dessus des nuages"
affiche("uneChaine=" + uneChaine)
affiche("uneChaine.Length=" & uneChaine.Length)
affiche("chaine[10]=" + uneChaine.Chars(10))
affiche("uneChaine.IndexOf(""vole"")=" & uneChaine.IndexOf("vole"))
affiche("uneChaine.IndexOf(""x"")=" & uneChaine.IndexOf("x"))
affiche("uneChaine.LastIndexOf('a')=" & uneChaine.LastIndexOf("a"c))
affiche("uneChaine.LastIndexOf('x')=" & uneChaine.LastIndexOf("x"c))
affiche("uneChaine.Substring(4,7)=" + uneChaine.Substring(4, 7))
affiche("uneChaine.ToUpper()=" + uneChaine.ToUpper())
affiche("uneChaine.ToLower()=" + uneChaine.ToLower())
affiche("uneChaine.Replace('a','A')=" + uneChaine.Replace("a"c, "A"c))
Dim champs As String() = uneChaine.Split(Nothing)
Dim i As Integer
For i = 0 To champs.Length - 1
affiche("champs[" & i & "]=[" & champs(i) & "]")
Next i
affiche("Join("":"",champs)=" + System.String.Join(":", champs))
affiche("("" abc "").Trim()=[" + " abc ".Trim() + "]")
End Sub
' يعرض
Sub affiche(ByVal msg As [String])
' عرض الرسالة
Console.Out.WriteLine(msg)
End Sub
End Module
يُنتج التنفيذ النتائج التالية:
dos>vbc string1.vb
dos>string1
uneChaine=l'oiseau vole au-dessus des nuages
uneChaine.Length=34
chaine[10]=o
uneChaine.IndexOf("vole")=9
uneChaine.IndexOf("x")=-1
uneChaine.LastIndexOf('a')=30
uneChaine.LastIndexOf('x')=-1
uneChaine.Substring(4,7)=seau vo
uneChaine.ToUpper()=L'OISEAU VOLE AU-DESSUS DES NUAGES
uneChaine.ToLower()=l'oiseau vole au-dessus des nuages
uneChaine.Replace('a','A')=l'oiseAu vole Au-dessus des nuAges
champs[0]=[l'oiseau]
champs[1]=[vole]
champs[2]=[au-dessus]
champs[3]=[des]
champs[4]=[nuages]
Join(":",champs)=l'oiseau:vole:au-dessus:des:nuages
(" abc ").Trim()=[abc]
لنأخذ مثالاً جديداً:
' خيارات
Option Strict On
Option Explicit On
' مساحات الأسماء
Imports System
Module string2
Sub Main()
' السطر المراد تحليله
Dim ligne As String = "un:deux::trois:"
' فواصل الحقول
Dim séparateurs() As Char = {":"c}
' التقسيم
Dim champs As String() = ligne.Split(séparateurs)
Dim i As Integer
For i = 0 To champs.Length - 1
Console.Out.WriteLine(("Champs[" & i & "]=" & champs(i)))
Next i
' الدمج
Console.Out.WriteLine(("join=[" + System.String.Join(":", champs) + "]"))
End Sub
End Module
ونظر إلى نتائج التنفيذ:
تسمح الطريقة Split الخاصة بالفئة String بتحويل حقول سلسلة أحرف إلى مصفوفة. وفيما يلي تعريف الطريقة المستخدمة هنا:
مصفوفة الأحرف. تمثل هذه الأحرف الأحرف المستخدمة لفصل حقول سلسلة الأحرف. وبالتالي، إذا كانت السلسلة هي [champ1, champ2, champ3]، فيمكن استخدام separator=new char() {","c}. وإذا كان الفاصل عبارة عن سلسلة من المسافات، فسيتم استخدام separator=nothing. | |
مصفوفة من سلاسل الأحرف حيث يمثل كل عنصر حقلًا في السلسلة. |
الطريقة Join هي طريقة ثابتة للفئة String:
مصفوفة من سلاسل الأحرف | |
سلسلة أحرف ستُستخدم كفاصل بين الحقول | |
سلسلة أحرف مكونة من ربط عناصر المصفوفة value بفاصل السلسلة separator. |
4.4. فئة Array
تُنفذ فئة Array مصفوفة. سنستخدم في مثالنا الخصائص والأساليب التالية:
الخاصية - عدد عناصر المصفوفة | |
طريقة الفئة - تُرجع موضع value في المصفوفة المُرتبة array - تبحث بدءًا من الموضع index وبمقدار length عنصرًا | |
طريقة الفئة - نسخ عناصر length من sourceArray إلى destinationArray - يتم إنشاء destinationArray لهذه الغاية | |
طريقة الفئة - ترتيب المصفوفة array - يجب أن تحتوي هذه المصفوفة على نوع بيانات له دالة ترتيب افتراضية (سلاسل، أرقام). |
يوضح البرنامج التالي استخدام الفئة Array:
' خيارات
Option Strict On
Option Explicit On
' مساحات الأسماء
Imports System
Module test
Sub Main()
' قراءة عناصر المصفوفة التي تم إدخالها عبر لوحة المفاتيح
Dim terminé As [Boolean] = False
Dim i As Integer = 0
Dim éléments1 As Double() = Nothing
Dim éléments2 As Double() = Nothing
Dim élément As Double = 0
Dim réponse As String = Nothing
Dim erreur As [Boolean] = False
While Not terminé
' السؤال
Console.Out.Write(("Elément (réel) " & i & " du tableau (rien pour terminer) : "))
' قراءة الإجابة
réponse = Console.ReadLine().Trim()
' إنهاء الإدخال إذا كانت السلسلة فارغة
If réponse.Equals("") Then
Exit While
End If
' التحقق من الإدخال
Try
élément = [Double].Parse(réponse)
erreur = False
Catch
Console.Error.WriteLine("Saisie incorrecte, recommencez")
erreur = True
End Try
' في حالة عدم وجود أخطاء
If Not erreur Then
' جدول جديد لاستيعاب العنصر الجديد
éléments2 = New Double(i) {}
' نسخ المصفوفة القديمة إلى المصفوفة الجديدة
If i <> 0 Then
Array.Copy(éléments1, éléments2, i)
End If
' يصبح الجدول الجديد هو الجدول القديم
éléments1 = éléments2
' لم يعد هناك حاجة إلى الجدول الجديد
éléments2 = Nothing
' إدراج عنصر جديد
éléments1(i) = élément
' عنصر إضافي في الجدول
i += 1
End If
End While
' عرض الجدول غير مرتب
System.Console.Out.WriteLine("Tableau non trié")
For i = 0 To éléments1.Length - 1
Console.Out.WriteLine(("éléments[" & i & "]=" & éléments1(i)))
Next i
' فرز الجدول
System.Array.Sort(éléments1)
' عرض الجدول مرتبًا
System.Console.Out.WriteLine("Tableau trié")
For i = 0 To éléments1.Length - 1
Console.Out.WriteLine(("éléments[" & i & "]=" & éléments1(i)))
Next i
' البحث
While Not terminé
' السؤال
Console.Out.Write("Elément cherché (rien pour arrêter) : ")
' قراءة الإجابة والتحقق منها
réponse = Console.ReadLine().Trim()
' انتهيت؟
If réponse.Equals("") Then
Exit While
End If
' التحقق
Try
élément = [Double].Parse(réponse)
erreur = False
Catch
Console.Error.WriteLine("Saisie incorrecte, recommencez")
erreur = True
End Try
' إذا لم تكن هناك أخطاء
If Not erreur Then
' نبحث عن العنصر في المصفوفة المرتبة
i = System.Array.BinarySearch(éléments1, 0, éléments1.Length, élément)
' عرض الإجابة
If i >= 0 Then
Console.Out.WriteLine(("Trouvé en position " & i))
Else
Console.Out.WriteLine("Pas dans le tableau")
End If
End If
End While
End Sub
End Module
نتائج العرض على الشاشة هي كما يلي:
Elément (réel) 0 du tableau (rien pour terminer) : 10,4
Elément (réel) 1 du tableau (rien pour terminer) : 5,2
Elément (réel) 2 du tableau (rien pour terminer) : 8,7
Elément (réel) 3 du tableau (rien pour terminer) : 3,6
Elément (réel) 4 du tableau (rien pour terminer) :
Tableau non trié
éléments[0]=10,4
éléments[1]=5,2
éléments[2]=8,7
éléments[3]=3,6
Tableau trié
éléments[0]=3,6
éléments[1]=5,2
éléments[2]=8,7
éléments[3]=10,4
Elément cherché (rien pour arrêter) : 8,7
Trouvé en position 2
Elément cherché (rien pour arrêter) : 11
Pas dans le tableau
Elément cherché (rien pour arrêter) : a
Saisie incorrecte, recommencez
Elément cherché (rien pour arrêter) :
يقوم الجزء الأول من البرنامج بإنشاء مصفوفة من البيانات الرقمية التي يتم إدخالها عبر لوحة المفاتيح. لا يمكن تحديد حجم المصفوفة مسبقًا نظرًا لعدم معرفة عدد العناصر التي سيقوم المستخدم بإدخالها. لذلك، يتم العمل باستخدام مصفوفتين هما éléments1 و éléments2.
' جدول جديد لاستيعاب العنصر الجديد
éléments2 = New Double(i) {}
' نسخ المصفوفة القديمة إلى المصفوفة الجديدة
If i <> 0 Then
Array.Copy(éléments1, éléments2, i)
End If
' يصبح الجدول الجديد هو الجدول القديم
éléments1 = éléments2
' لم يعد هناك حاجة إلى الجدول الجديد
éléments2 = Nothing
' إدراج عنصر جديد
éléments1(i) = élément
' عنصر إضافي في الجدول
i += 1
يحتوي الجدول éléments1 على القيم التي تم إدخالها حاليًا. عندما يضيف المستخدم قيمة جديدة، يتم إنشاء جدول éléments2 يحتوي على عنصر واحد أكثر من éléments1، ويتم نسخ محتوى éléments1 إلى éléments2 (Array.Copy)، نجعل éléments1 «يشير» إلى éléments2، وأخيرًا نضيف العنصر الجديد إلى éléments1. هذه عملية معقدة يمكن تبسيطها إذا استخدمنا مصفوفة متغيرة الحجم (ArrayList) بدلاً من مصفوفة ذات حجم ثابت (Array).
يتم فرز المصفوفة باستخدام الطريقة Array.Sort. يمكن استدعاء هذه الطريقة بمعلمات مختلفة تحدد قواعد الفرز. في حالة عدم وجود معلمات، يتم الفرز افتراضيًّا بترتيب تصاعدي. وأخيرًا، تتيح الطريقة Array.BinarySearch البحث عن عنصر في مصفوفة مفروزة.
4.5. الفئة ArrayList
تسمح الفئة ArrayList بتنفيذ مصفوفات ذات أحجام متغيرة أثناء تشغيل البرنامج، وهو ما لا تسمح به الفئة السابقة Array. فيما يلي بعض الخصائص والطرق الشائعة:
تنشئ قائمة فارغة | |
عدد عناصر المجموعة | |
يضيف الكائن value إلى نهاية المجموعة | |
يُمسح القائمة | |
رقم الكائن value في القائمة أو -1 إذا لم يكن موجودًا | |
نفس الشيء ولكن بالبحث بدءًا من العنصر رقم startIndex | |
نفس الشيء ولكن مع إرجاع مؤشر آخر ظهور لـ value في القائمة | |
نفس الشيء، لكن البحث يبدأ من العنصر رقم startIndex | |
حذف الكائن obj إذا كان موجودًا في القائمة | |
يُزيل العنصر index من القائمة | |
تُرجع موضع العنصر «value» في القائمة أو -1 إذا لم يكن موجودًا فيها. يجب أن تكون القائمة مرتبة | |
يُرتب القائمة. يجب أن تحتوي القائمة على كائنات ذات علاقة ترتيب محددة مسبقًا (سلاسل، أرقام) | |
تقوم بفرز القائمة وفقًا لعلاقة الترتيب التي حددتها دالة المقارنة |
لنعد إلى المثال الذي تم تناوله باستخدام كائنات من النوع Array ونعالجه باستخدام كائنات من النوع ArrayList:
' خيارات
Option Strict On
Option Explicit On
' مساحات الأسماء
Imports System
Imports System.Collections
Module test
Sub Main()
' قراءة عناصر الجدول التي تم إدخالها عبر لوحة المفاتيح
Dim terminé As [Boolean] = False
Dim i As Integer = 0
Dim éléments As New ArrayList
Dim élément As Double = 0
Dim réponse As String = Nothing
Dim erreur As [Boolean] = False
While Not terminé
' سؤال
Console.Out.Write(("Elément (réel) " & i & " du tableau (rien pour terminer) : "))
' قراءة الرد
réponse = Console.ReadLine().Trim()
' إنهاء الإدخال إذا كانت السلسلة فارغة
If réponse.Equals("") Then
Exit While
End If
' التحقق من الإدخال
Try
élément = Double.Parse(réponse)
erreur = False
Catch
Console.Error.WriteLine("Saisie incorrecte, recommencez")
erreur = True
End Try
' في حالة عدم وجود أخطاء
If Not erreur Then
' عنصر إضافي في الجدول
éléments.Add(élément)
End If
End While
' عرض المصفوفة غير المرتبة
System.Console.Out.WriteLine("Tableau non trié")
For i = 0 To éléments.Count - 1
Console.Out.WriteLine(("éléments[" & i & "]=" & éléments(i).ToString))
Next i ' tri du tableau
éléments.Sort()
' عرض المصفوفة مرتبة
System.Console.Out.WriteLine("Tableau trié")
For i = 0 To éléments.Count - 1
Console.Out.WriteLine(("éléments[" & i & "]=" & éléments(i).ToString))
Next i
' بحث
While Not terminé
' السؤال
Console.Out.Write("Elément cherché (rien pour arrêter) : ")
' قراءة الإجابة والتحقق منها
réponse = Console.ReadLine().Trim()
' انتهيت؟
If réponse.Equals("") Then
Exit While
End If
' التحقق
Try
élément = [Double].Parse(réponse)
erreur = False
Catch
Console.Error.WriteLine("Saisie incorrecte, recommencez")
erreur = True
End Try
' إذا لم تكن هناك أخطاء
If Not erreur Then
' نبحث عن العنصر في المصفوفة المرتبة
i = éléments.BinarySearch(élément)
' عرض الإجابة
If i >= 0 Then
Console.Out.WriteLine(("Trouvé en position " & i))
Else
Console.Out.WriteLine("Pas dans le tableau")
End If
End If
End While
End Sub
End Module
نتائج التنفيذ هي كما يلي:
Elément (réel) 0 du tableau (rien pour terminer) : 10,4
Elément (réel) 0 du tableau (rien pour terminer) : 5,2
Elément (réel) 0 du tableau (rien pour terminer) : a
Saisie incorrecte, recommencez
Elément (réel) 0 du tableau (rien pour terminer) : 3,7
Elément (réel) 0 du tableau (rien pour terminer) : 15
Elément (réel) 0 du tableau (rien pour terminer) :
Tableau non trié
éléments[0]=10,4
éléments[1]=5,2
éléments[2]=3,7
éléments[3]=15
Tableau trié
éléments[0]=3,7
éléments[1]=5,2
éléments[2]=10,4
éléments[3]=15
Elément cherché (rien pour arrêter) : a
Saisie incorrecte, recommencez
Elément cherché (rien pour arrêter) : 15
Trouvé en position 3
Elément cherché (rien pour arrêter) : 1
Pas dans le tableau
Elément cherché (rien pour arrêter) :
4.6. فئة Hashtable
تسمح الفئة Hashtable بتنفيذ قاموس. يمكن النظر إلى القاموس على أنه مصفوفة ذات عمودين:
![]() |
المفاتيح فريدة، c.a.d. ولا يمكن أن يكون هناك مفتاحان متطابقان. فيما يلي الطرق والخصائص الرئيسية لفئة Hashtable:
ينشئ قاموسًا فارغًا | |
يضيف سطراً (key,value) إلى القاموس حيث key و value هما مرجعان لكائنين. | |
يحذف السطر الذي يحتوي على المفتاح key من القاموس | |
يُفرغ القاموس | |
تُرجع القيمة «صحيح» (true) إذا كان المفتاح key موجودًا في القاموس. | |
| تُرجع القيمة «صحيح» (true) إذا كانت القيمة value موجودة في القاموس. |
الخاصية: عدد عناصر القاموس (المفتاح، القيمة) | |
الخاصية: مجموعة مفاتيح القاموس | |
الخاصية: مجموعة قيم القاموس | |
الخاصية المفهرسة: تسمح بمعرفة أو تحديد القيمة المرتبطة بمفتاح key |
لنأخذ البرنامج التالي كمثال:
' خيارات
Option Strict On
Option Explicit On
' مساحات الأسماء
Imports System
Imports System.Collections
Module test
Sub Main()
Dim liste() As [String] = {"jean:20", "paul:18", "mélanie:10", "violette:15"}
Dim i As Integer
Dim champs As [String]() = Nothing
Dim séparateurs() As Char = {":"c}
' ملء القاموس
Dim dico As New Hashtable
For i = 0 To liste.Length - 1
champs = liste(i).Split(séparateurs)
dico.Add(champs(0), champs(1))
Next i
' عدد العناصر في القاموس
Console.Out.WriteLine(("Le dictionnaire a " & dico.Count & " éléments"))
' قائمة المفاتيح
Console.Out.WriteLine("[Liste des clés]")
Dim clés As IEnumerator = dico.Keys.GetEnumerator()
While clés.MoveNext()
Console.Out.WriteLine(clés.Current)
End While
' قائمة القيم
Console.Out.WriteLine("[Liste des valeurs]")
Dim valeurs As IEnumerator = dico.Values.GetEnumerator()
While valeurs.MoveNext()
Console.Out.WriteLine(valeurs.Current)
End While
' قائمة المفاتيح والقيم
Console.Out.WriteLine("[Liste des clés & valeurs]")
clés.Reset()
While clés.MoveNext()
Console.Out.WriteLine(("clé=" & clés.Current.ToString & " valeur=" & dico(clés.Current).ToString))
End While
' حذف المفتاح "paul"
Console.Out.WriteLine("[Suppression d'une clé]")
dico.Remove("paul")
' قائمة بالمفاتيح والقيم
Console.Out.WriteLine("[Liste des clés & valeurs]")
clés = dico.Keys.GetEnumerator()
While clés.MoveNext()
Console.Out.WriteLine(("clé=" & clés.Current.ToString & " valeur=" & dico(clés.Current).ToString))
End While
' البحث في القاموس
Dim nomCherché As [String] = Nothing
Console.Out.Write("Nom recherché (rien pour arrêter) : ")
nomCherché = Console.ReadLine().Trim()
Dim value As [Object] = Nothing
While Not nomCherché.Equals("")
If dico.ContainsKey(nomCherché) Then
value = dico(nomCherché)
Console.Out.WriteLine((nomCherché + "," + CType(value, [String])))
Else
Console.Out.WriteLine(("Nom " + nomCherché + " inconnu"))
End If
' البحث التالي
Console.Out.Write("Nom recherché (rien pour arrêter) : ")
nomCherché = Console.ReadLine().Trim()
End While
End Sub
End Module
نتائج التنفيذ هي كما يلي:
Le dictionnaire a 4 éléments
[Liste des clés]
mélanie
paul
violette
jean
[Liste des valeurs]
10
18
15
20
[Liste des clés & valeurs]
clé=mélanie valeur=10
clé=paul valeur=18
clé=violette valeur=15
clé=jean valeur=20
[Suppression d'une clé]
[Liste des clés & valeurs]
clé=mélanie valeur=10
clé=violette valeur=15
clé=jean valeur=20
Nom recherché (rien pour arrêter) : paul
Nom paul inconnu
Nom recherché (rien pour arrêter) : mélanie
mélanie,10
Nom recherché (rien pour arrêter) :
يستخدم البرنامج أيضًا كائن IEnumerator لتصفح مجموعات المفاتيح والقيم في القاموس من النوع ICollection (انظر أعلاه الخصائص Keys و Values). المجموعة هي مجموعة من الكائنات التي يمكن تصفحها. يتم تعريف الواجهة ICollection على النحو التالي:

تسمح لنا الخاصية Count بمعرفة عدد عناصر المجموعة. تنبثق الواجهة ICollection من الواجهة IEnumerable:

تحتوي هذه الواجهة على طريقة واحدة فقط هي GetEnumerator التي تتيح لنا الحصول على كائن من النوع IEnumerator:

تتيح لنا الطريقة GetEnumerator() الخاصة بمجموعة ICollection تصفح المجموعة باستخدام الطرق التالية:
يحدد العنصر التالي في المجموعة. تُرجع القيمة «صحيح» (true) إذا كان هذا العنصر موجودًا، و«خطأ» (false) في حالة عدم وجوده. يُحدد الأمر الأول MoveNext العنصر الأول. ويصبح العنصر «الحالي» في المجموعة متاحًا عندئذٍ في الخاصية Current للمُعدِّد | |
الخاصية: العنصر الحالي في المجموعة | |
يعيد وضع المؤشر في بداية المجموعة، c.a.d، قبل العنصر الأول. |
وبالتالي، فإن بنية التكرار على عناصر المجموعة (ICollection) في لغة C هي كما يلي:
' تحديد المجموعة
dim C as ICollection C=...
' الحصول على مؤشر لهذه المجموعة
dim itérateur as IEnumerator=C.GetEnumerator();
' تصفح المجموعة باستخدام هذا المؤشر
while(itérateur.MoveNext())
' لدينا عنصر حالي
' استخدام itérateur.Current
end while
4.7. الفئة StreamReader
تسمح الفئة StreamReader بقراءة محتوى ملف. فيما يلي بعض خصائصها وأساليبها:
تفتح دفقًا من الملف path. يتم إلقاء استثناء إذا كان الملف غير موجود | |
يغلق الدفق | |
يقرأ سطراً من الدفق المفتوح | |
يقرأ باقي الدفق بدءًا من الموضع الحالي |
فيما يلي مثال:
' خيارات
Option Strict On
Option Explicit On
' مساحات الأسماء
Imports System
Imports System.Collections
Imports System.IO
Module test
Sub Main()
Dim ligne As String = Nothing
Dim fluxInfos As StreamReader = Nothing
' قراءة محتوى الملف
Try
fluxInfos = New StreamReader("infos.txt")
ligne = fluxInfos.ReadLine()
While Not (ligne Is Nothing)
System.Console.Out.WriteLine(ligne)
ligne = fluxInfos.ReadLine()
End While
Catch e As Exception
System.Console.Error.WriteLine("L'erreur suivante s'est produite : " & e.ToString)
Finally
Try
fluxInfos.Close()
Catch
End Try
End Try
End Sub
End Module
ونتيجة التنفيذ:
dos>more infos.txt
12620:0:0
13190:0,05:631
15640:0,1:1290,5
24740:0,15:2072,5
31810:0,2:3309,5
39970:0,25:4900
48360:0,3:6898,5
55790:0,35:9316,5
92970:0,4:12106
127860:0,45:16754,5
151250:0,5:23147,5
172040:0,55:30710
195000:0,6:39312
0:0,65:49062
dos>file1
12620:0:0
13190:0,05:631
15640:0,1:1290,5
24740:0,15:2072,5
31810:0,2:3309,5
39970:0,25:4900
48360:0,3:6898,5
55790:0,35:9316,5
92970:0,4:12106
127860:0,45:16754,5
151250:0,5:23147,5
172040:0,55:30710
195000:0,6:39312
0:0,65:49062
4.8. الفئة StreamWriter
تسمح الفئة StreamWriter بالكتابة في ملف. فيما يلي بعض خصائصها وأساليبها:
تفتح تدفق كتابة من الملف path. يتم إلقاء استثناء إذا تعذر إنشاء هذا الملف | |
إذا كانت القيمة «صحيح»، فإن الكتابة في الدفق لا تمر عبر ذاكرة مؤقتة؛ وإلا فإن الكتابة في الدفق لا تتم فورًا: حيث تتم الكتابة أولاً في ذاكرة مؤقتة ثم في الدفق عندما تمتلئ الذاكرة المؤقتة. بشكل افتراضي، يتم استخدام الوضع المؤقت. وهو مناسب تمامًا لدفقات الملفات ولكنه غير مناسب عمومًا لدفقات الشبكة. | |
لتحديد أو معرفة علامة نهاية السطر التي ستستخدمها الطريقة WriteLine | |
يغلق التدفق | |
يكتب سطراً في تدفق الكتابة | |
يكتب محتوى المخزن المؤقت في الدفق |
لنأخذ المثال التالي:
' خيارات
Option Strict On
Option Explicit On
' مساحات الأسماء
Imports System
Imports System.Collections
Imports System.IO
Module test
Sub Main()
Dim ligne As String = Nothing ' une ligne de texte
Dim fluxInfos As StreamWriter = Nothing ' le fichier texte
Try
' إنشاء ملف نصي
fluxInfos = New StreamWriter("infos.txt")
' قراءة السطر المكتوب على لوحة المفاتيح
Console.Out.Write("ligne (rien pour arrêter) : ")
ligne = Console.In.ReadLine().Trim()
' تكرار العملية ما دام السطر المدخل غير فارغ
While ligne <> ""
' كتابة السطر في ملف نصي
fluxInfos.WriteLine(ligne)
' قراءة سطر جديد من لوحة المفاتيح
Console.Out.Write("ligne (rien pour arrêter) : ")
ligne = Console.In.ReadLine().Trim()
End While
Catch e As Exception
System.Console.Error.WriteLine("L'erreur suivante s'est produite : " & e.ToString)
Finally
' إغلاق الملف
Try
fluxInfos.Close()
Catch
End Try
End Try
End Sub
End Module
ونتيجة التنفيذ:
dos>file2
ligne (rien pour arrêter) : ligne1
ligne (rien pour arrêter) : ligne2
ligne (rien pour arrêter) : ligne3
ligne (rien pour arrêter) :
dos>more infos.txt
ligne1
ligne2
ligne3
4.9. فئة Regex
تسمح الفئة Regex باستخدام التعبيرات النمطية. تتيح هذه التعبيرات التحقق من تنسيق سلسلة أحرف. وبذلك يمكن التأكد من أن السلسلة التي تمثل تاريخًا تتوافق بالفعل مع التنسيق يي/ش/س. وللقيام بذلك، يتم استخدام نموذج ومقارنة السلسلة بهذا النموذج. وفي هذا المثال، يجب أن تكون الأحرف j و m و a أرقامًا. ونموذج تنسيق التاريخ الصحيح هو «\d\d/\d\d/\d\d»، حيث يشير الرمز \d إلى رقم. الرموز التي يمكن استخدامها في النموذج هي التالية (وثائق مايكروسوفت):
الوصف | |
يُشير إلى الحرف التالي على أنه حرف خاص أو حرف حرفي. على سبيل المثال، «n» يمثل الحرف «n». «\n» يمثل حرفًا لبدء سطر جديد. التسلسل «\\» يمثل «\»، بينما «\(" يمثل «(». | |
يمثل بداية الإدخال. | |
يمثل نهاية الإدخال. | |
يتطابق مع الحرف السابق صفر مرة أو عدة مرات. وبالتالي، فإن "zo*" يتطابق مع "z" أو "zoo". | |
يتطابق مع الحرف السابق مرة واحدة أو أكثر. وبالتالي، فإن "zo+" يتطابق مع "zoo"، ولكنه لا يتطابق مع "z". | |
يتطابق مع الحرف السابق صفر مرة أو مرة واحدة. على سبيل المثال، "a?ve?" يتطابق مع "ve" في كلمة "lever". | |
يتطابق مع أي حرف فردي، باستثناء حرف السطر الجديد. | |
| يبحث عن modèle ويحفظ المطابقة. يمكن استخراج السلسلة الفرعية المطابقة من مجموعة Matches التي تم الحصول عليها، باستخدام العنصر [0]...[n]. للعثور على التطابقات التي تحتوي على أحرف بين قوسين ( )، استخدم "\(" أو "\)". |
| يتطابق إما مع x أو مع y. على سبيل المثال، "z|foot" يتطابق مع "z" أو مع "foot". "(z|f)oo" يتطابق مع "zoo" أو مع "foo". |
| n هو عدد صحيح غير سالب. يتطابق تمامًا مع n مضروبًا في الحرف. على سبيل المثال، "o{2}" لا يتطابق مع "o" في "Bob"، بل مع أول حرفين "o" في "fooooot". |
| n هو عدد صحيح غير سالب. يتطابق مع ما لا يقل عن n ضعف الحرف. على سبيل المثال، لا يتطابق "o{2,}" مع الحرف "o" في كلمة "Bob"، بل مع جميع أحرف "o" في كلمة "fooooot". ويُعتبر "o{1,}" مكافئًا لـ "o+"، و"o{0,}" مكافئًا لـ "o*". |
| m و n هما عددان صحيحان غير سالبين. يعني ظهور الحرف ما لا يقل عن n وما لا يزيد عن m مرة. على سبيل المثال، «o{1,3}» يشير إلى الأحرف «o» الثلاثة الأولى في «foooooot»، و«o{0,1}» يعادل «o?». |
| مجموعة الأحرف. تتطابق مع أحد الأحرف المحددة. على سبيل المثال، "[abc]" تتطابق مع الحرف "a" في كلمة "plat". |
| مجموعة الأحرف السلبية. تتطابق مع أي حرف غير مذكور. على سبيل المثال، "[^abc]" تتطابق مع الحرف "p" في كلمة "plat". |
| نطاق الأحرف. يطابق أي حرف ضمن السلسلة المحددة. على سبيل المثال، "[a-z]" يطابق أي حرف أبجدي صغير بين "a" و"z". |
| نطاق أحرف سلبي. يطابق أي حرف غير موجود في السلسلة المحددة. على سبيل المثال، "[^m-z]" يطابق أي حرف غير موجود بين "m" و"z". |
يتطابق مع حد يمثل كلمة، أي الموضع بين كلمة ومسافة. على سبيل المثال، "er\b" يتطابق مع "er" في كلمة "lever"، ولكنه لا يتطابق مع "er" في كلمة "verbe". | |
يمثل حدًا لا يمثل كلمة. «en*t\B» يمثل «ent» في كلمة «bien entendu». | |
يتطابق مع حرف يمثل رقمًا. يعادل [0-9]. | |
يتوافق مع حرف لا يمثل رقمًا. يعادل [^0-9]. | |
يمثل حرف تخطي الصفحة. | |
يمثل حرفًا لبدء سطر جديد. | |
يُقابل حرف الرجوع إلى السطر. | |
يمثل أي مسافة بيضاء، بما في ذلك المسافة، وعلامة الجدولة، وقفزة الصفحة، وما إلى ذلك. يعادل "[ \f\n\r\t\v]". | |
يمثل أي حرف فراغ غير أبيض. يعادل "[^ \f\n\r\t\v]". | |
يتطابق مع حرف الجدولة. | |
يمثل حرف الجدولة العمودية. | |
يمثل أي حرف يمثل كلمة ويتضمن شرطة سفلية. يعادل "[A-Za-z0-9_]". | |
يمثل أي حرف لا يمثل كلمة. يعادل "[^A-Za-z0-9_]". | |
| يتوافق مع num، حيث num هو عدد صحيح موجب. يشير إلى المطابقات المخزنة. على سبيل المثال، "(.)\1" يتوافق مع حرفين متطابقين متتاليين. |
| يُقابل n، حيث n هو قيمة هروب ثمانية. يجب أن تتألف قيم الهروب الثمانية من 1 أو 2 أو 3 أرقام. على سبيل المثال، يُقابل كل من "\11" و"\011" حرف جدولة واحد. "\0011" تعادل "\001" و"1". يجب ألا تتجاوز قيم الهروب الثمانية 256. إذا تجاوزت هذا الحد، فلن يؤخذ في الاعتبار سوى أول رقمين في التعبير. تسمح باستخدام الرموز ASCII في التعبيرات النمطية. |
| تتوافق مع n، حيث n هي قيمة هروب سداسية عشرية. يجب أن تتكون قيم الهروب السداسية العشرية من رقمين على الأقل. على سبيل المثال، "\x41" تعني "A". و"\x041" تعادل "\x04" و"1". تسمح باستخدام الرموز ASCII في التعبيرات النمطية. |
يمكن أن يظهر عنصر ما في القالب مرة واحدة أو عدة مرات. لنأخذ بعض الأمثلة حول الرمز \d الذي يمثل رقمًا واحدًا:
القالب | المعنى |
رقم واحد | |
رقم واحد أو صفر | |
صفر أو أكثر من رقم | |
رقم واحد أو أكثر | |
رقمان | |
3 أرقام على الأقل | |
ما بين 5 و7 أرقام |
لنتخيل الآن النموذج القادر على وصف التنسيق المتوقع لسلسلة الأحرف:
السلسلة المطلوبة | النموذج |
\d{2}/\d{2}/\d{2} | |
\d{2}:\d{2}:\d{2} | |
\d+ | |
\s* | |
\s*\d+\s* | |
\s*[+|-]?\s*\d+\s* | |
\s*\d+(.\d*)?\s* | |
\s*[+|]?\s*\d+(.\d*)?\s* | |
\bjuste\b | |
يمكن تحديد مكان البحث عن النمط في السلسلة:
النمط | المعنى |
يبدأ النموذج السلسلة | |
ينتهي النموذج بالسلسلة | |
يبدأ القالب السلسلة وينهيها | |
يتم البحث عن النمط في جميع أنحاء السلسلة بدءًا من بدايتها. |
السلسلة المطلوب البحث عنها | النمط |
!$ | |
\.$ | |
^// | |
^\s*\w+\s*$ | |
^\s*\w+\s*\w+\s*$ | |
\bsecret\b |
يمكن "استخراج" المجموعات الفرعية لنموذج ما. وبالتالي، لا يمكننا فقط التحقق من أن سلسلة ما تتطابق مع نموذج معين، بل يمكننا أيضًا استخراج العناصر الموجودة في هذه السلسلة والتي تتطابق مع المجموعات الفرعية للنموذج التي تم وضعها بين أقواس. فإذا قمنا بتحليل سلسلة تحتوي على تاريخ jj/mm/aa وأردنا أيضًا استخراج العناصر jj و mm و aa من هذا التاريخ، فسنستخدم النموذج (\d\d)/(\d\d)/(\d\d).
4.9.1. التحقق من مطابقة سلسلة نصية لنموذج معين
يتم إنشاء كائن من نوع Regex بالطريقة التالية:
يقوم المنشئ بإنشاء كائن «التعبير النمطي» استنادًا إلى نموذج يتم تمريره كمعلمة (pattern). وبمجرد إنشاء التعبير النمطي النموذجي، يمكن مقارنته بسلاسل الأحرف باستخدام الطريقة IsMatch:
تُرجع الدالة IsMatch القيمة «صحيح» إذا كانت السلسلة المدخلة تتطابق مع نموذج التعبير العادي. وفيما يلي مثال على ذلك:
' خيارات
Option Strict On
Option Explicit On
' مساحات الأسماء
Imports System
Imports System.Collections
Imports System.Text.RegularExpressions
Module regex1
Sub Main()
' نمط تعبير منتظم
Dim modèle1 As String = "^\s*\d+\s*$"
Dim regex1 As New Regex(modèle1)
' مقارنة نسخة بالنموذج
Dim exemplaire1 As String = " 123 "
If regex1.IsMatch(exemplaire1) Then
affiche(("[" + exemplaire1 + "] correspond au modèle [" + modèle1 + "]"))
Else
affiche(("[" + exemplaire1 + "] ne correspond pas au modèle [" + modèle1 + "]"))
End If
Dim exemplaire2 As String = " 123a "
If regex1.IsMatch(exemplaire2) Then
affiche(("[" + exemplaire2 + "] correspond au modèle [" + modèle1 + "]"))
Else
affiche(("[" + exemplaire2 + "] ne correspond pas au modèle [" + modèle1 + "]"))
End If
End Sub
' عرض
Sub affiche(ByVal msg As String)
Console.Out.WriteLine(msg)
End Sub
End Module
وإليك نتائج التنفيذ:
dos>vbc /r:system.dll regex1.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4 pour Microsoft (R) .NET Framework version 1.1.4322.573
dos>regex1
[ 123 ] correspond au modèle [^\s*\d+\s*$]
[ 123a ] ne correspond pas au modèle [^\s*\d+\s*$]
4.9.2. البحث عن جميع العناصر في سلسلة تتطابق مع نمط معين
طريقة Matches
مجموعة من العناصر في السلسلة input التي تتطابق مع النمط كما هو موضح في المثال التالي:
' خيارات
Option Strict On
Option Explicit On
' مساحات الأسماء
Imports System
Imports System.Collections
Imports System.Text.RegularExpressions
Module regex2
Sub Main()
' تكررات متعددة للنموذج في النسخة
Dim modèle2 As String = "\d+"
Dim regex2 As New Regex(modèle2) '
Dim exemplaire3 As String = " 123 456 789 "
Dim résultats As MatchCollection = regex2.Matches(exemplaire3)
affiche(("Modèle=[" + modèle2 + "],exemplaire=[" + exemplaire3 + "]"))
affiche(("Il y a " & résultats.Count & " occurrences du modèle dans l'exemplaire "))
Dim i As Integer
For i = 0 To résultats.Count - 1
affiche((résultats(i).Value & " en position " & résultats(i).Index))
Next i
End Sub
'عرض
Sub affiche(ByVal msg As String)
Console.Out.WriteLine(msg)
End Sub
End Module
تحتوي الفئة MatchCollection على خاصية Count التي تمثل عدد عناصر المجموعة. إذا كان résultats كائنًا من نوع MatchCollection، فإن résultats(i) هو العنصر i في هذه المجموعة وهو من النوع Match. في مثالنا، يمثل résultats مجموعة العناصر في السلسلة exemplaire3 المطابقة للنموذج modèle2، ويمثل résultats(i) أحد هذه العناصر. تحتوي الفئة Match على خاصيتين تهماننا هنا:
- Value: قيمة الكائن Match، أي العنصر المطابق للنموذج
- Index: الموضع الذي تم العثور فيه على العنصر في السلسلة التي تم استكشافها
نتائج تنفيذ البرنامج السابق:
dos>vbc /r:system.dll regex2.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4p our Microsoft (R) .NET Framework version 1.1.4322.573
dos>regex2
Modèle=[\d+],exemplaire=[ 123 456 789 ]
Il y a 3 occurrences du modèle dans l'exemplaire
123 en position 2
456 en position 7
789 en position 12
4.9.3. استخراج أجزاء من نموذج
يمكن "استخراج" مجموعات فرعية من نموذج ما. وبذلك، لا يمكننا فقط التحقق من أن سلسلة ما تتطابق مع نموذج معين، بل يمكننا أيضًا استخراج العناصر الموجودة في هذه السلسلة والتي تتطابق مع المجموعات الفرعية للنموذج التي تم وضعها بين أقواس. فإذا قمنا بتحليل سلسلة تحتوي على تاريخ jj/mm/aa وأردنا أيضًا استخراج العناصر jj و mm و aa من هذا التاريخ، فسنستخدم النموذج (\d\d)/(\d\d)/(\d\d). لنلقِ نظرة على المثال التالي:
' خيارات
Option Strict On
Option Explicit On
' مساحات الأسماء
Imports System
Imports System.Collections
Imports System.Text.RegularExpressions
Module regex2
Sub Main()
' التقاط العناصر في القالب
Dim modèle3 As String = "(\d\d):(\d\d):(\d\d)"
Dim regex3 As New Regex(modèle3)
Dim exemplaire4 As String = "Il est 18:05:49"
' التحقق من النموذج
Dim résultat As Match = regex3.Match(exemplaire4)
If résultat.Success Then
' النسخة تتطابق مع النموذج
affiche(("L'exemplaire [" + exemplaire4 + "] correspond au modèle [" + modèle3 + "]"))
' يتم عرض المجموعات
Dim i As Integer
For i = 0 To résultat.Groups.Count - 1
affiche(("groupes[" & i & "]=[" & résultat.Groups(i).Value & "] en position " & résultat.Groups(i).Index))
Next i
Else
' النسخة لا تتطابق مع النموذج
affiche(("L'exemplaire[" + exemplaire4 + " ne correspond pas au modèle [" + modèle3 + "]"))
End If
End Sub
'يُعرض
Sub affiche(ByVal msg As String)
Console.Out.WriteLine(msg)
End Sub
End Module
يُنتج تنفيذ هذا البرنامج النتائج التالية:
dos>vbc /r:system.dll regex3.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4
dos>regex3
L'exemplaire [Il est 18:05:49] correspond au modèle [(\d\d):(\d\d):(\d\d)]
groupes[0]=[18:05:49] en position 7
groupes[1]=[18] en position 7
groupes[2]=[05] en position 10
groupes[3]=[49] en position 13
يكمن التغيير في الجزء التالي من الكود:
' التحقق من النموذج
Dim résultat As Match = regex3.Match(exemplaire4)
If résultat.Success Then
' النسخة تتطابق مع النموذج
affiche(("L'exemplaire [" + exemplaire4 + "] correspond au modèle [" + modèle3 + "]"))
' يتم عرض المجموعات
Dim i As Integer
For i = 0 To résultat.Groups.Count - 1
affiche(("groupes[" & i & "]=[" & résultat.Groups(i).Value & "] en position " & résultat.Groups(i).Index))
Next i
Else
تتم مقارنة السلسلة exemplaire4 بالنموذج regex3 من خلال الطريقة Match. وتُرجع هذه الطريقة كائن Match الذي تم عرضه سابقًا. نستخدم هنا خاصيتين جديدتين من هذه الفئة:
- Success: تشير إلى ما إذا كان هناك تطابق أم لا
- Groups: مجموعة حيث
- Groups[0] يمثل الجزء من السلسلة المطابق للنموذج
- Groups[i] (i>=1) تتطابق مع مجموعة الأقواس رقم i
إذا كانت النتيجة من النوع Match، فإن résultats.Groups من النوع GroupCollection، وrésultats.Groups[i] من النوع Group. تحتوي الفئة Group على خاصيتين نستخدمهما هنا:
- Value: قيمة كائن Group التي تمثل العنصر المطابق لمحتوى القوس
- Index: الموضع الذي تم العثور فيه على العنصر في السلسلة التي تم استكشافها
4.9.4. برنامج تدريبي
قد يمثل العثور على التعبير النمطي الذي يسمح لنا بالتحقق من مطابقة سلسلة ما لنموذج معين تحديًا حقيقيًّا في بعض الأحيان. يتيح البرنامج التالي التدرب على ذلك. فهو يطلب نموذجًا وسلسلة، ثم يشير إلى ما إذا كانت السلسلة تتطابق مع النموذج أم لا.
' خيارات
Option Strict On
Option Explicit On
' مساحات الأسماء
Imports System
Imports System.Collections
Imports System.Text.RegularExpressions
Imports Microsoft.visualbasic
Module regex4
Sub Main()
' تعبير منتظم نموذجي
Dim modèle, chaine As String
Dim regex As Regex = Nothing
Dim résultats As MatchCollection
' يُطلب من المستخدم تحديد النماذج والنسخ التي سيتم مقارنتها بهذا النموذج
Dim terminé1 As Boolean = False
Do While Not terminé1
Dim erreur As Boolean = True
Do While Not terminé1 And erreur
' يُطلب النموذج
Console.Out.Write("Tapez le modèle à tester ou fin pour arrêter :")
modèle = Console.In.ReadLine()
' انتهى؟
If modèle.Trim().ToLower() = "fin" Then
terminé1 = True
Else
' يتم إنشاء التعبير النمطي
Try
regex = New Regex(modèle)
erreur = False
Catch ex As Exception
Console.Error.WriteLine(("Erreur : " + ex.Message))
End Try
End If
Loop
' هل انتهيت؟
If terminé1 Then Exit Sub
' يُطلب من المستخدم تحديد النسخ التي سيتم مقارنتها بالنموذج
Dim terminé2 As Boolean = False
Do While Not terminé2
Console.Out.Write(("Tapez la chaîne à comparer au modèle [" + modèle + "] ou fin pour arrêter :"))
chaine = Console.In.ReadLine()
' انتهى؟
If chaine.Trim().ToLower() = "fin" Then
terminé2 = True
Else
' نقوم بإجراء المقارنة
résultats = regex.Matches(chaine)
' نجاح؟
If résultats.Count = 0 Then
Console.Out.WriteLine("Je n'ai pas trouvé de correspondances")
Else
' يتم عرض العناصر المطابقة للنموذج
Dim i As Integer
For i = 0 To résultats.Count - 1
Console.Out.WriteLine(("J'ai trouvé la correspondance [" & résultats(i).Value & "] en position " & résultats(i).Index))
' العناصر الفرعية
If résultats(i).Groups.Count <> 1 Then
Dim j As Integer
For j = 1 To (résultats(i).Groups.Count) - 1
Console.Out.WriteLine((ControlChars.Tab & "sous-élément [" & résultats(i).Groups(j).Value & "] en position " & résultats(i).Groups(j).Index))
Next j
End If
Next i
End If
End If
Loop
Loop
End Sub
'يعرض
Sub affiche(ByVal msg As String)
Console.Out.WriteLine(msg)
End Sub
End Module
فيما يلي مثال على التنفيذ:
Tapez le modèle à tester ou fin pour arrêter :\d+
Tapez la chaîne à comparer au modèle [\d+] ou fin pour arrêter :123 456 789
J'ai trouvé la correspondance [123] en position 0
J'ai trouvé la correspondance [456] en position 4
J'ai trouvé la correspondance [789] en position 8
Tapez la chaîne à comparer au modèle [\d+] ou fin pour arrêter :fin
Tapez le modèle à tester ou fin pour arrêter :(\d\d):(\d\d)
Tapez la chaîne à comparer au modèle [(\d\d):(\d\d)] ou fin pour arrêter :14:15 abcd 17:18 xyzt
J'ai trouvé la correspondance [14:15] en position 0
sous-élément [14] en position 0
sous-élément [15] en position 3
J'ai trouvé la correspondance [17:18] en position 11
sous-élément [17] en position 11
sous-élément [18] en position 14
Tapez la chaîne à comparer au modèle [(\d\d):(\d\d)] ou fin pour arrêter :fin
Tapez le modèle à tester ou fin pour arrêter :^\s*\d+\s*$
Tapez la chaîne à comparer au modèle [^\s*\d+\s*$] ou fin pour arrêter : 1456
J'ai trouvé la correspondance [ 1456] en position 0
Tapez la chaîne à comparer au modèle [^\s*\d+\s*$] ou fin pour arrêter :fin
Tapez le modèle à tester ou fin pour arrêter :^\s*(\d+)\s*$
Tapez la chaîne à comparer au modèle [^\s*(\d+)\s*$] ou fin pour arrêter :1456
J'ai trouvé la correspondance [1456] en position 0
sous-élément [1456] en position 0
Tapez la chaîne à comparer au modèle [^\s*(\d+)\s*$] ou fin pour arrêter :abcd 1
456
Je n'ai pas trouvé de correspondances
Tapez la chaîne à comparer au modèle [^\s*(\d+)\s*$] ou fin pour arrêter :fin
Tapez le modèle à tester ou fin pour arrêter :fin
4.9.5. طريقة Split
لقد سبق أن تعرفنا على هذه الطريقة في الفصل String:
يُنظر إلى السلسلة على أنها سلسلة من الحقول مفصولة بالأحرف الموجودة في المصفوفة [separator]. والنتيجة هي مصفوفة هذه الحقول.
فاصل الحقول في السلسلة هنا هو أحد الأحرف الموجودة في الجدول separator. تتيح لنا الطريقة Split التابعة للفئة Regex التعبير عن الفاصل وفقًا لنموذج:
يتم تقسيم السلسلة [input] إلى حقول، حيث يتم فصل هذه الحقول بفاصل يتوافق مع نموذج الكائن Regex الحالي. لنفترض على سبيل المثال أن لدينا في ملف نصي أسطرًا بالصيغة «الحقل1، الحقل2، ...، الحقلn». تُفصل الحقول بفاصلة، لكن قد تسبقها أو تتبعها مسافات. وبالتالي، فإن الطريقة Split الخاصة بالفئة string غير مناسبة في هذه الحالة. أما الطريقة RegEx فهي التي توفر الحل. إذا كان «line» هو السطر الذي تمت قراءته، فيمكن الحصول على الحقول من خلال
كما يوضح المثال التالي:
' الخيارات
Option Strict On
Option Explicit On
' مساحات الأسماء
Imports System
Imports System.Text.RegularExpressions
Module regex5
Sub Main()
' سطر
Dim ligne As String = "abc , def , ghi"
' قالب
Dim modèle As New Regex("\s*,\s*")
' تقسيم السطر إلى حقول
Dim champs As String() = modèle.Split(ligne)
' العرض
Dim i As Integer
For i = 0 To champs.Length - 1
Console.Out.WriteLine(("champs[" & i & "]=[" & champs(i) & "]"))
Next i
End Sub
End Module
نتائج التنفيذ:
dos>vbc /r:system.dll regex5.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4
dos>regex5
champs[0]=[abc]
champs[1]=[def]
champs[2]=[ghi]
4.10. الفئتان BinaryReader و BinaryWriter
تُستخدم الفئتان BinaryReader و BinaryWriter لقراءة وكتابة الملفات الثنائية. لنأخذ التطبيق التالي كمثال. نريد كتابة برنامج يُسمى على النحو التالي:
// صياغة pg نص ثنائي
// قراءة ملف نصي (نص) وتخزين محتواه في
// ملف ثنائي
// يحتوي الملف النصي على أسطر بالصيغة التالية: الاسم : العمر
// والتي سيتم تخزينها في بنية من نوع string و int
يحتوي الملف النصي على المحتوى التالي:
البرنامج هو كما يلي:
' خيارات
Option Strict On
Option Explicit On
' مساحات الأسماء
Imports System
Imports System.Text.RegularExpressions
Imports System.IO
' BinaryWriter()
Module bw1
' صياغة pg نص ثنائي
' يتم قراءة ملف نصي (نص) وتخزين محتواه في
' ملف ثنائي
' يحتوي الملف النصي على أسطر بالصيغة الاسم: العمر
' التي سيتم تخزينها في بنية string، int
Sub Main(ByVal arguments() As String)
' يلزم وجود معلمتين
Dim nbArgs As Integer = arguments.Length
If nbArgs <> 2 Then
Console.Error.WriteLine("syntaxe : pg texte binaire")
Environment.Exit(1)
End If
' فتح الملف النصي للقراءة
Dim input As StreamReader = Nothing
Try
input = New StreamReader(arguments(0))
Catch ex As Exception
Console.Error.WriteLine("Erreur d'ouverture du fichier " & arguments(0) & "(" & ex.Message & ")")
Environment.Exit(2)
End Try
' فتح الملف الثنائي للكتابة
Dim output As BinaryWriter = Nothing
Try
output = New BinaryWriter(New FileStream(arguments(1), FileMode.Create, FileAccess.Write))
Catch ex As Exception
Console.Error.WriteLine("Erreur d'ouverture du fichier " & arguments(1) & "(" & ex.Message & ")")
Environment.Exit(3)
End Try
' قراءة ملف نصي - كتابة ملف ثنائي
' سطر من الملف النصي
Dim ligne As String
' فاصل الحقول في السطر
Dim séparateur As New Regex("\s*:\s*")
' نموذج العمر
Dim modAge As New Regex("\s*\d+\s*")
Dim numLigne As Integer = 0
Dim traitementFini As Boolean
Dim champs As String()
ligne = input.ReadLine()
While Not (ligne Is Nothing)
traitementFini = False
' سطر فارغ؟
If ligne.Trim() = "" Then
traitementFini = True
End If
' سطر إضافي
If Not traitementFini Then
numLigne += 1
' سطر اسم: العمر
champs = séparateur.Split(ligne)
' نحتاج إلى حقلين
If champs.Length <> 2 Then
Console.Error.WriteLine(("La ligne n° " & numLigne & " du fichier " & arguments(0) & " a un nombre de champs incorrect"))
' السطر التالي
traitementFini = True
End If
End If
If Not traitementFini Then
' يجب أن يكون الحقل الثاني عددًا صحيحًا >=0
If Not modAge.IsMatch(champs(1)) Then
Console.Error.WriteLine(("La ligne n° " & numLigne & " du fichier " & arguments(0) & " a un âge incorrect"))
' السطر التالي
traitementFini = True
End If
' نقوم بكتابة البيانات في الملف الثنائي
output.Write(champs(0))
output.Write(Integer.Parse(champs(1)))
End If
'السطر التالي
ligne = input.ReadLine()
End While
' إغلاق الملفات
input.Close()
output.Close()
End Sub
End Module
لنركز على العمليات المتعلقة بالفئة BinaryWriter:
- يتم فتح الكائن BinaryWriter بواسطة العملية
output = New BinaryWriter(New FileStream(arguments(1), FileMode.Create, FileAccess.Write))
يجب أن تكون وسيطة المنشئ عبارة عن دفق (Stream). وهنا، يتعلق الأمر بدفق تم إنشاؤه من ملف (FileStream) الذي نحدد له:
- (تابع)
- الاسم
- العملية المطلوب تنفيذها، وهي هنا FileMode.Create لإنشاء الملف
- نوع الوصول، وهو هنا FileAccess.Write للوصول إلى الملف بوضع الكتابة
- عملية الكتابة
' يتم كتابة البيانات في الملف الثنائي
output.Write(champs(0))
output.Write(Integer.Parse(champs(1)))
تحتوي الفئة BinaryWriter على طرق مختلفة Write مُثبَّتة لكتابة أنواع مختلفة من البيانات البسيطة
- عملية إغلاق التدفق
سيقدم لنا البرنامج التالي نتائج التنفيذ السابق. ويقبل هذا البرنامج أيضًا حجتين:
' صيغة pg bin text
' قراءة ملف ثنائي بن وتخزين محتواه في ملف نصي (نص)
' الملف الثنائي له بنية string، int
' يحتوي الملف النصي على أسطر بالصيغة اسم : عمر
لذلك نقوم بالعملية العكسية. نقوم بقراءة ملف ثنائي لإنشاء ملف نصي. إذا كان الملف النصي الناتج مطابقًا للملف الأصلي، فسنعرف أن عملية التحويل من نص إلى ثنائي ثم إلى نص قد تمت بنجاح. والرمز هو كما يلي:
' خيارات
Option Strict On
Option Explicit On
' مساحات الأسماء
Imports System
Imports System.Text.RegularExpressions
Imports System.IO
Module br1
' صيغة pg bin text
' يتم قراءة ملف ثنائي بن وتخزين محتواه في ملف نصي (نص)
' الملف الثنائي له بنية string، int
' يحتوي الملف النصي على أسطر بالصيغة اسم : عمر
Sub Main(ByVal arguments() As String)
' يلزم وجود معلمتين
Dim nbArgs As Integer = arguments.Length
If nbArgs <> 2 Then
Console.Error.WriteLine("syntaxe : pg binaire texte")
Environment.Exit(1)
End If
' فتح الملف الثنائي للقراءة
Dim dataIn As BinaryReader = Nothing
Try
dataIn = New BinaryReader(New FileStream(arguments(0), FileMode.Open, FileAccess.Read))
Catch ex As Exception
Console.Error.WriteLine("Erreur d'ouverture du fichier " & arguments(0) & "(" & ex.Message & ")")
Environment.Exit(2)
End Try
' فتح الملف النصي للكتابة
Dim dataOut As StreamWriter = Nothing
Try
dataOut = New StreamWriter(arguments(1))
dataOut.AutoFlush = True
Catch ex As Exception
Console.Error.WriteLine("Erreur d'ouverture du fichier " & arguments(1) & "(" & ex.Message & ")")
Environment.Exit(3)
End Try
' قراءة الملف الثنائي - كتابة الملف النصي
Dim nom As String ' nom d'une personne
Dim age As Integer ' son âge
' حلقة معالجة الملف الثنائي
While True
' قراءة الاسم
Try
nom = dataIn.ReadString()
Catch
' نهاية الملف
Exit Sub
End Try
' قراءة العمر
Try
age = dataIn.ReadInt32()
Catch
Console.Error.WriteLine("Le fichier " & arguments(0) + " ne semble pas avoir un format correct")
Exit Sub
End Try
' الكتابة في ملف نصي
dataOut.WriteLine(nom & ":" & age)
System.Console.WriteLine(nom & ":" & age)
End While
' إغلاق كل شيء
dataIn.Close()
dataOut.Close()
End Sub
End Module
لنركز على العمليات المتعلقة بالفئة BinaryReader:
- يتم فتح الكائن BinaryReader بواسطة العملية
dataIn = New BinaryReader(New FileStream(arguments(0), FileMode.Open, FileAccess.Read))
يجب أن تكون وسيطة المنشئ عبارة عن دفق (Stream). وهنا، يتعلق الأمر بدفق تم إنشاؤه من ملف (FileStream) الذي نقدم له:
- (تابع)
- الاسم
- العملية المطلوب تنفيذها، وهي هنا FileMode.Open لفتح ملف موجود
- نوع الوصول، وهو هنا FileAccess.Read للوصول إلى الملف للقراءة
- عملية القراءة
تحتوي الفئة BinaryReader على طرق مختلفة ReadXX لقراءة أنواع مختلفة من البيانات البسيطة
- عملية إغلاق التدفق
إذا تم تنفيذ البرنامجين بالتسلسل لتحويل personnes.txt إلى personnes.bin ثم personnes.bin إلى personnes.txt2، نحصل على:

