Skip to content

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.

Image

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

Image

من هناك، انقر على رابط [مكتبة الفئات]. يحتوي هذا الرابط على قائمة بجميع فئات .NET:

Image

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

Image

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

Image

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

Image

لاحظ موضع المؤشر أدناه. إنه يشير إلى رابط يتيح لك تحديد اللغة المطلوبة، وهي في هذه الحالة Visual Basic.

ستجد هنا نموذج الفئة بالإضافة إلى أمثلة الاستخدام. انقر على الرابط [Hashtable, Members] أدناه:

Image

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

Image

هذه الطريقة هي أفضل وسيلة لاستكشاف SDK وفئاته. تكون أداة WinCV مفيدة عندما تكون لديك معرفة مسبقة بسيطة بالفئة ولكنك نسيت بعض أعضائها. تتيح لك WinCV عندئذ العثور بسرعة على الفئة وأعضائها.

4.2. البحث عن المساعدة بشأن الفئات باستخدام VS.NET

فيما يلي بعض النصائح للعثور على المساعدة باستخدام Visual Studio.NET

4.2.1. خيار المساعدة

حدد الخيار [?] من القائمة.

Image

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

Image

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

Image

هناك نوعان من المساعدة المفيدة:

  • المساعدة الخاصة بلغة VB.NET نفسها (الصياغة)
  • المساعدة بشأن فئات .NET التي يمكن استخدامها بواسطة لغة VB.NET

يمكن الوصول إلى مساعدة لغة VB.NET عبر [Visual Studio.NET/Visual Basic و Visual C#/Reference/Visual Basic]:

Image

يؤدي هذا إلى ظهور صفحة المساعدة التالية:

Image

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

Image

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

Image

سنركز بشكل خاص على قسم [Reference/Class Library]:

Image

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

Image

يقدم الرابط [ArrayList، الفئة] لمحة عامة عن الفئة:

Image

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

Image

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

Image

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

Image

ميزة هذه الطريقة على الطريقة السابقة هي أنك لست بحاجة إلى معرفة مكان العثور على ما تبحث عنه في نظام المساعدة. من المرجح أن تكون هذه هي الطريقة المفضلة للبحث المحدد، في حين أن الطريقة الأخرى أكثر ملاءمة لاستكشاف كل ما يقدمه نظام المساعدة.

4.3. فئة String

تحتوي فئة String على العديد من الخصائص والطرق. فيما يلي بعض منها:

خاصية عامة للقراءة فقط Length كعدد صحيح
عدد الأحرف في السلسلة
خاصية عامة للقراءة فقط
Chars(ByVal index كعدد صحيح) كحرف
خاصية مفهرسة افتراضية. [String].Chars(i) هي الحرف i من السلسلة
دالة عامة EndsWith(ByVal value As String)
As Boolean
تُرجع القيمة true إذا كانت السلسلة تنتهي بالقيمة
دالة عامة StartsWith(ByVal value As String)
كقيمة منطقية
تُرجع القيمة "صحيح" إذا كانت السلسلة تبدأ بالقيمة
تحميلات الدالة العامة Equals(ByVal value
As String) As Boolean
تُرجع القيمة "صحيح" إذا كانت السلسلة مساوية للقيمة
تحميلات إضافية للدالة العامة IndexOf(ByVal value
As String) As Integer
تُرجع الموضع الأول في السلسلة الذي توجد فيه قيمة السلسلة — يبدأ البحث من الحرف 0
تحميلات إضافية للدالة العامة IndexOf(ByVal value
As String, ByVal startIndex As Integer) As Integer
تُرجع موضع أول ظهور لقيمة السلسلة في السلسلة — يبدأ البحث عند مؤشر الحرف startIndex
تحميلات إضافية للدالة العامة المشتركة
Join(ByVal separator As String, ByVal value()
As String) As String
طريقة فئة - تُرجع سلسلة ناتجة عن ربط القيم الموجودة في صفيفة value باستخدام الفاصل separator
تحميلات إضافية للوظيفة العامة Replace(ByVal oldChar
As Char, ByVal newChar As Char) As String
تُرجع نسخة من السلسلة الحالية حيث تم استبدال الحرف oldChar بالحرف newChar
تحميلات إضافية Public Function Split(ByVal ParamArray
separator() As Char) As String()
يتم التعامل مع السلسلة على أنها تسلسل من الحقول مفصولة بالأحرف الموجودة في مصفوفة الفاصل. والنتيجة هي مصفوفة من هذه الحقول
تحميل الدالة العامة Substring(
ByVal startIndex As Integer, ByVal length As Integer)
As String
سلسلة فرعية من السلسلة الحالية تبدأ من الموضع startIndex وتحتوي على length حرفًا
تحميلات إضافية للدالة العامة ToLower()
As String
تحويل السلسلة الحالية إلى أحرف صغيرة
تحميلات إضافية للدالة العامة ToUpper()
كـ String
يحول السلسلة الحالية إلى أحرف كبيرة
تحميل الدالة العامة Trim()
كـ String
يزيل المسافات في بداية ونهاية السلسلة الحالية

يمكن اعتبار سلسلة C مصفوفة من الأحرف. وبالتالي

  • C.Chars(i) هو الحرف رقم i في C
  • C.Length هو عدد الأحرف في C

انظر المثال التالي:


' options
Option Strict On
Option Explicit On 
 
' namespaces
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
 
    ' poster
    Sub affiche(ByVal msg As [String])
        ' poster msg
        Console.Out.WriteLine(msg)
    End Sub
End Module

يؤدي التنفيذ إلى النتائج التالية:

dos>vbc string1.vb

dos>string1
uneChaine=l'bird flies above the clouds
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 ABOVE DES NUAGES
uneChaine.ToLower()=l'bird flies above the clouds
uneChaine.Replace('a','A')=l'oiseAu flies Over the nuAges
champs[0]=[l'bird]
champs[1]=[vole]
champs[2]=[au-dessus]
champs[3]=[des]
champs[4]=[nuages]
Join(":",champs)=l'bird:flies:above:clouds
("  abc  ").Trim()=[abc]

لنأخذ مثالاً جديداً:


' options
Option Strict On
Option Explicit On 
 
' namespaces
Imports System
 
Module string2
    Sub Main()
        ' the line to be analyzed
        Dim ligne As String = "un:deux::trois:"
        ' field separators
        Dim séparateurs() As Char = {":"c}
        ' split
        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
        ' join
        Console.Out.WriteLine(("join=[" + System.String.Join(":", champs) + "]"))
    End Sub
End Module

ونتيجة التنفيذ:

Champs[0]=un
Champs[1]=deux
Champs[2]=
Champs[3]=trois
Champs[4]=
join=[un:deux::trois:]

تسمح لك طريقة Split الخاصة بفئة String بوضع حقول سلسلة نصية في مصفوفة. فيما يلي تعريف الطريقة المستخدمة هنا:

Overloads Public Function Split(ByVal ParamArray separator() As Char) As String()
separator
مصفوفة من الأحرف. تمثل هذه الأحرف الأحرف المستخدمة لفصل الحقول في السلسلة. وبالتالي، إذا كانت السلسلة هي [field1, field2, field3]، فيمكننا استخدام separator=new char() {","c}. إذا كان الفاصل عبارة عن سلسلة من المسافات، فإننا نستخدم separator=nothing.
النتيجة
مصفوفة من السلاسل حيث يكون كل عنصر حقلًا من السلسلة.

طريقة Join هي طريقة ثابتة لفئة String:

Overloads Public Shared Function Join(ByVal separator As String, ByVal value() As String) As String
القيمة
مصفوفة من السلاسل
فاصل
سلسلة ستعمل كفاصل للحقول
النتيجة
سلسلة يتم تكوينها عن طريق ربط عناصر مصفوفة القيمة، مفصولة بسلسلة الفاصل.

4.4. فئة Array

تنفذ فئة Array مصفوفة. في مثالنا، سنستخدم الخصائص والطرق التالية:

خاصية عامة للقراءة فقط Length كعدد صحيح
الخاصية - عدد العناصر في المصفوفة
تحميلات Public Shared Function BinarySearch
(ByVal array As Array, ByVal index As Integer,
ByVal length كعدد صحيح، ByVal value ككائن) كعدد صحيح
طريقة الفئة - تُرجع موضع القيمة في المصفوفة المُرتبة - تبحث بدءًا من الموضع index وبطول length عناصر
تحميلات عامة مشتركة Sub Copy(ByVal sourceArray
As Array، ByVal destinationArray As Array،
ByVal length As Integer)
طريقة الفئة - تنسخ العناصر الأولى بطول length من sourceArray إلى destinationArray - يتم إنشاء destinationArray خصيصًا لهذا الغرض
تحميلات إضافية Public Shared Sub Sort(ByVal array As Array)
طريقة فئة - تقوم بفرز المصفوفة - يجب أن تحتوي المصفوفة على نوع بيانات مع وظيفة فرز افتراضية (سلاسل، أرقام).

يوضح البرنامج التالي استخدام فئة Array:


' options
Option Strict On
Option Explicit On 
 
' namespaces
Imports System
 
Module test
    Sub Main()
        ' read table elements typed on keyboard
        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é
            ' question
            Console.Out.Write(("Elément (réel) " & i & " du tableau (rien pour terminer) : "))
            ' reading the answer
            réponse = Console.ReadLine().Trim()
            ' end of input if string empty
            If réponse.Equals("") Then
                Exit While
            End If
            ' input verification
            Try
                élément = [Double].Parse(réponse)
                erreur = False
            Catch
                Console.Error.WriteLine("Saisie incorrecte, recommencez")
                erreur = True
            End Try
            ' if no error
            If Not erreur Then
                ' new table to accommodate the new element
                éléments2 = New Double(i) {}
                ' copy old panel to new panel
                If i <> 0 Then
                    Array.Copy(éléments1, éléments2, i)
                End If
                ' new table becomes old table
                éléments1 = éléments2
                ' no need for the new panel
                éléments2 = Nothing
                ' insert new element
                éléments1(i) = élément
                ' one more element in the picture
                i += 1
            End If
        End While
        ' unsorted table display
        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
        ' table sorting
        System.Array.Sort(éléments1)
        ' sorted table display
        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
        ' Search
        While Not terminé
            ' question
            Console.Out.Write("Elément cherché (rien pour arrêter) : ")
            ' reading-checking response
            réponse = Console.ReadLine().Trim()
            ' finished?
            If réponse.Equals("") Then
                Exit While
            End If
            ' check
            Try
                élément = [Double].Parse(réponse)
                erreur = False
            Catch
                Console.Error.WriteLine("Saisie incorrecte, recommencez")
                erreur = True
            End Try
            ' if no error
            If Not erreur Then
                ' search for the element in the sorted array
                i = System.Array.BinarySearch(éléments1, 0, éléments1.Length, élément)
                ' Display response
                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) :

يقوم الجزء الأول من البرنامج بإنشاء مصفوفة من البيانات الرقمية التي يتم إدخالها عبر لوحة المفاتيح. لا يمكن تحديد المصفوفة مسبقًا لأننا لا نعرف عدد العناصر التي سيقوم المستخدم بإدخالها. لذلك، نعمل مع مصفوفتين، elements1 و elements2.


                ' nouveau tableau pour accueillir le nouvel élément
                éléments2 = New Double(i) {}
                ' copie ancien tableau vers nouveau tableau
                If i <> 0 Then
                    Array.Copy(éléments1, éléments2, i)
                End If
                ' nouveau tableau devient ancien tableau
                éléments1 = éléments2
                ' plus besoin du nouveau tableau
                éléments2 = Nothing
                ' insertion nouvel élément
                éléments1(i) = élément
                ' un élémt de plus dans le tableau
                i += 1

يحتوي المصفوف elements1 على القيم التي تم إدخالها حالياً. عندما يضيف المستخدم قيمة جديدة، نقوم بإنشاء مصفوفة elements2 تحتوي على عنصر واحد أكثر من elements1، ونسخ محتويات elements1 إلى elements2 (Array.Copy)، وتعيين elements1 للإشارة إلى elements2، وأخيراً إضافة العنصر الجديد إلى elements1. هذه عملية معقدة يمكن تبسيطها باستخدام مصفوفة ذات حجم متغير (ArrayList) بدلاً من مصفوفة ذات حجم ثابت (Array).

يتم فرز المصفوفة باستخدام طريقة Array.Sort. يمكن استدعاء هذه الطريقة بمعلمات متنوعة تحدد قواعد الفرز. وفي حالة عدم وجود معلمات، يتم الفرز تصاعديًا بشكل افتراضي. وأخيرًا، تتيح لك طريقة Array.BinarySearch البحث عن عنصر في مصفوفة مفروزة.

4.5. فئة ArrayList

تسمح لك فئة ArrayList بتنفيذ مصفوفات ذات حجم متغير أثناء تنفيذ البرنامج، وهو ما لا تسمح به فئة Array السابقة. فيما يلي بعض الخصائص والطرق الشائعة:

Public Sub New()
تنشئ قائمة فارغة
خاصية عامة قابلة للتجاوز للقراءة فقط Count
كعدد صحيح  تنفذ ICollection.Count
عدد العناصر في المجموعة
دالة عامة قابلة للتجاوز Add(ByVal value
As Object) As Integer Implements IList.Add
يضيف كائن القيمة إلى نهاية المجموعة
Public Overridable Sub Clear()
يُنفذ IList.Clear
يُفرغ القائمة
تحميل وظيفة عامة قابلة للتجاوز
IndexOf(ByVal value As Object) As Integer
تنفذ IList.IndexOf
مؤشر كائن القيمة في القائمة أو -1 إذا لم يكن موجودًا
تحميلات الدالة العامة القابلة للتجاوز
IndexOf(ByVal value As Object, ByVal startIndex
As Integer) As Integer
مثل ما سبق، ولكن بدءًا من العنصر startIndex
تحميلات إضافية للوظيفة العامة القابلة للتجاوز
LastIndexOf(ByVal value As Object) As Integer
مثل ما سبق، ولكنها تُرجع مؤشر آخر ظهور للقيمة في القائمة
تحميلات وظيفة عامة قابلة للتجاوز
LastIndexOf(ByVal value As Object, ByVal startIndex As Integer) As Integer
مثل ما سبق، ولكن بدءًا من العنصر الموجود في startIndex
Public Overridable Sub Remove(ByVal obj As Object)
يُنفذ IList.Remove
تقوم بإزالة الكائن obj إذا كان موجودًا في القائمة
دالة عامة قابلة للتجاوز RemoveAt(ByVal index As Integer)
يُنفذ IList.RemoveAt
يزيل العنصر الموجود في الفهرس من القائمة
تحميلات الدالة العامة القابلة للتجاوز
BinarySearch(ByVal value As Object) As Integer
تُرجع موضع كائن القيمة في القائمة، أو -1 إذا لم يتم العثور عليه. يجب أن تكون القائمة مرتبة
تحميلات إضافية للوظيفة الفرعية العامة القابلة للتجاوز Sort()
يقوم بفرز القائمة. يجب أن تحتوي القائمة على كائنات ذات علاقة ترتيب محددة مسبقًا (سلاسل، أرقام)
التحميلات الزائدة Public Overridable Sub
Sort(ByVal comparer As IComparer)
يقوم بفرز القائمة وفقًا للترتيب الذي تحدده دالة المقارنة

دعونا نراجع المثال باستخدام كائنات Array ونطبقه على كائنات ArrayList:


' options
Option Strict On
Option Explicit On 
 
' namespaces
Imports System
Imports System.Collections
 
Module test
    Sub Main()
        ' read table elements typed on keyboard
        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é
            ' question
            Console.Out.Write(("Elément (réel) " & i & " du tableau (rien pour terminer) : "))
            ' reading the answer
            réponse = Console.ReadLine().Trim()
            ' end of input if string empty
            If réponse.Equals("") Then
                Exit While
            End If
            ' input verification
            Try
                élément = Double.Parse(réponse)
                erreur = False
            Catch
                Console.Error.WriteLine("Saisie incorrecte, recommencez")
                erreur = True
            End Try
            ' if no error
            If Not erreur Then
                ' one more element in the picture
                éléments.Add(élément)
            End If
        End While
        ' unsorted table display
        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        ' table sorting
        éléments.Sort()
        ' sorted table display
        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
        ' Search
        While Not terminé
            ' question
            Console.Out.Write("Elément cherché (rien pour arrêter) : ")
            ' reading-checking response
            réponse = Console.ReadLine().Trim()
            ' finished?
            If réponse.Equals("") Then
                Exit While
            End If
            ' check
            Try
                élément = [Double].Parse(réponse)
                erreur = False
            Catch
                Console.Error.WriteLine("Saisie incorrecte, recommencez")
                erreur = True
            End Try
            ' if no error
            If Not erreur Then
                ' search for the element in the sorted array
                i = éléments.BinarySearch(élément)
                ' Display response
                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 بتنفيذ قاموس. يمكن النظر إلى القاموس على أنه مصفوفة من عمودين:

المفاتيح فريدة؛ أي لا يمكن أن يكون هناك مفتاحان متطابقان. فيما يلي الطرق والخصائص الرئيسية لفئة Hashtable:

Public Sub New()
ينشئ قاموسًا فارغًا
Public Overridable Sub Add(ByVal key As
Object, ByVal value As Object)
يُنفذ IDictionary.Add
تضيف إدخالاً (المفتاح، القيمة) إلى القاموس، حيث يمثل كل من المفتاح والقيمة مرجعاً إلى كائن.
Public Overridable Sub Remove
(ByVal key As Object) Implements IDictionary.Remove
يزيل الإدخال الذي يحتوي على key=key من القاموس
Public Overridable Sub Clear()
تنفذ IDictionary.Clear
يُفرغ القاموس
دالة عامة قابلة للتجاوز ContainsKey
(ByVal key As Object) As Boolean
تُرجع القيمة true إذا كان المفتاح key موجودًا في القاموس.
دالة عامة قابلة للتجاوز
ContainsValue(ByVal value As Object) As Boolean
تُرجع القيمة true إذا كانت القيمة value موجودة في القاموس.
خاصية عامة قابلة للتجاوز للقراءة فقط
Count كعدد صحيح  تنفذ ICollection.Count
الخاصية: عدد العناصر في القاموس (المفتاح، القيمة)
خاصية عامة قابلة للتجاوز للقراءة فقط
Keys كـ ICollection تنفذ IDictionary.Keys
الخاصية: مجموعة مفاتيح القاموس
خاصية عامة قابلة للتجاوز للقراءة فقط
القيم كـ ICollection تنفذ IDictionary.Values
الخاصية: مجموعة من قيم القاموس
خاصية عامة قابلة للتجاوز افتراضية
Item(ByVal key As Object) As Object  تنفذ IDictionary.Item
خاصية مفهرسة: تسمح لك باسترداد أو تعيين القيمة المرتبطة بمفتاح

انظر إلى البرنامج التالي كمثال:


' options
Option Strict On
Option Explicit On 
 
' namespaces
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}
        ' filling the dictionary
        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
        ' number of elements in the dictionary
        Console.Out.WriteLine(("Le dictionnaire a " & dico.Count & " éléments"))
        ' kEY LIST
        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
        ' list of values
        Console.Out.WriteLine("[Liste des valeurs]")
        Dim valeurs As IEnumerator = dico.Values.GetEnumerator()
        While valeurs.MoveNext()
            Console.Out.WriteLine(valeurs.Current)
        End While
        ' list of keys & values
        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
        ' delete the "paul" key
        Console.Out.WriteLine("[Suppression d'une clé]")
        dico.Remove("paul")
        ' list of keys & values
        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
 
        ' dictionary search
        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
            ' next search
            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 (انظر خصائص المفاتيح والقيم أعلاه). المجموعة هي مجموعة من الكائنات التي يمكن التكرار عليها. يتم تعريف واجهة ICollection على النحو التالي:

Image

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

Image

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

Image

تسمح لنا طريقة GetEnumerator() الخاصة بـ ICollection بالتكرار عبر المجموعة باستخدام الطرق التالية:

التالي
ينتقل إلى العنصر التالي في المجموعة. يُرجع القيمة true إذا كان هذا العنصر موجودًا، وإلا يُرجع القيمة false. ينتقل أول استدعاء لـ MoveNext إلى العنصر الأول. يصبح العنصر "الحالي" للمجموعة متاحًا بعد ذلك في الخاصية Current للمُعدد
Current
: العنصر الحالي للمجموعة
إعادة التعيين
يعيد تعيين المكرر إلى بداية المجموعة، أي قبل العنصر الأول.

وبالتالي، فإن بنية التكرار على عناصر مجموعة C (ICollection) هي كما يلي:

' define collection
dim C as ICollection C=...
' get an enumerator of this collection
dim itérateur as IEnumerator=C.GetEnumerator();
' browse the collection with this enumerator
while(itérateur.MoveNext())
    ' we have a current element
    ' operate itérateur.Current
end while

4.7. فئة StreamReader

تسمح لك فئة StreamReader بقراءة محتويات ملف. فيما يلي بعض خصائصها وأساليبها:

Public Sub New(ByVal path As String)
تفتح دفقًا من مسار الملف. يتم إصدار استثناء إذا كان الملف غير موجود
تتجاوز Public Sub Close()
يغلق الدفق
يتجاوز الدالة العامة ReadLine() كسلسلة
يقرأ سطراً من الدفق المفتوح
تجاوز الدالة العامة ReadToEnd() كسلسلة
يقرأ باقي الدفق من الموضع الحالي

فيما يلي مثال:


' options
Option Strict On
Option Explicit On 
 
' namespaces
Imports System
Imports System.Collections
Imports System.IO
 
Module test
    Sub Main()
        Dim ligne As String = Nothing
        Dim fluxInfos As StreamReader = Nothing
        ' read file content
        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 بالكتابة إلى ملف. فيما يلي بعض خصائصها وأساليبها:

Public Sub New(ByVal path As String)
يفتح دفق كتابة من مسار الملف. يتم إصدار استثناء إذا تعذر إنشاء الدفق
Public Overridable Property AutoFlush
As Boolean
إذا تم تعيينها على true، فإن الكتابة إلى الدفق تتجاوز المخزن المؤقت؛ وإلا، فإن الكتابة إلى الدفق لا تتم على الفور: يتم أولاً كتابة البيانات إلى مخزن مؤقت ثم إلى الدفق عندما يمتلئ المخزن المؤقت. بشكل افتراضي، يتم استخدام الوضع المؤقت. وهو مناسب تمامًا لدفق الملفات ولكنه غير مناسب عمومًا لدفق الشبكة.
خاصية عامة قابلة للتجاوز NewLine
كـ String
لتعيين أو استرداد حرف نهاية السطر المستخدم بواسطة الأسلوب WriteLine
تتجاوز Public Sub Close()
يغلق الدفق
تحميل عامة قابلة للتجاوز Sub
WriteLine(ByVal value As String)
يكتب سطراً إلى دفق الكتابة
تجاوز الدالة العامة Flush()
يفرغ المخزن المؤقت إلى الدفق

انظر المثال التالي:


' options
Option Strict On
Option Explicit On 
 
' namespaces
Imports System
Imports System.Collections
Imports System.IO
 
Module test
    Sub Main()
        Dim ligne As String = Nothing        ' one line of text
        Dim fluxInfos As StreamWriter = Nothing        ' the text file
        Try
            ' text file creation
            fluxInfos = New StreamWriter("infos.txt")
            ' read line typed on keyboard
            Console.Out.Write("ligne (rien pour arrêter) : ")
            ligne = Console.In.ReadLine().Trim()
            ' loop as long as the line entered is not empty
            While ligne <> ""
                ' write line to text file
                fluxInfos.WriteLine(ligne)
                ' read new line on keyboard
                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
            ' close file
            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 باستخدام التعبيرات العادية. وتُستخدم هذه التعبيرات للتحقق من صحة تنسيق سلسلة. على سبيل المثال، يمكنك التحقق من أن سلسلة تمثل تاريخًا بتنسيق dd/mm/yy. للقيام بذلك، تستخدم نمطًا وتقارن السلسلة بهذا النمط. في هذا المثال، يجب أن تكون d و m و y أرقامًا. وبالتالي، فإن النمط الخاص بتنسيق التاريخ الصحيح هو "\d\d/\d\d/\d\d"، حيث يمثل الرمز \d رقمًا. الرموز التي يمكن استخدامها في النمط هي كما يلي (وثائق Microsoft):

 
الوصف
\
يُشير إلى الحرف التالي كحرف خاص أو حرفي. على سبيل المثال، "n" يُشير إلى الحرف "n". "\n" يُشير إلى حرف السطر الجديد. التسلسل "\\" يُشير إلى "\"، بينما "\(" يُشير إلى "(".
^
يطابق بداية الإدخال.
$
يتطابق مع نهاية المدخلات.
*
يطابق الحرف السابق صفر أو أكثر من مرة. وبالتالي، فإن "zo*" يطابق "z" أو "zoo".
+
يطابق الحرف السابق مرة واحدة أو أكثر. وبالتالي، فإن "zo+" يطابق "zoo"، ولكنه لا يطابق "z".
?
يتطابق مع الحرف السابق صفر أو مرة واحدة. على سبيل المثال، "a?ve?" يتطابق مع "ve" في "lever".
.
يتطابق مع أي حرف واحد، باستثناء حرف السطر الجديد.

(النمط)
يبحث عن النمط ويخزن المطابقة. يمكن استرداد السلسلة الفرعية المطابقة من مجموعة Matches الناتجة باستخدام Item [0]...[n]. لمطابقة الأحرف المحاطة بأقواس ( )، استخدم "\(" أو "\)".
x|y
يطابق إما x أو y. على سبيل المثال، يطابق "z|foot" "z" أو "foot". يطابق "(z|f)oo" "zoo" أو "foo".

{n}
n هو عدد صحيح غير سالب. يطابق n مرة بالضبط من ظهور الحرف. على سبيل المثال، "o{2}" لا يطابق "o" في "Bob"، ولكنه يطابق أول حرفين "o" في "fooooot".

{n,}
n هو عدد صحيح غير سالب. يطابق ما لا يقل عن n تكرارًا للحرف. على سبيل المثال، "o{2,}" لا يطابق "o" في "Bob"، ولكنه يطابق جميع أحرف "o" في "fooooot". "o{1,}" يعادل "o+" و "o{0,}" يعادل "o*".

{n,m}
m و n عددان صحيحان غير سالبين. يطابق ما لا يقل عن n وما لا يزيد عن m تكرارات للحرف. على سبيل المثال، يطابق "o{1,3}" الأحرف الثلاثة الأولى من نوع "o" في الكلمة "foooooot"، أما "o{0,1}" فيعادل "o?".

[xyz]
مجموعة أحرف. يطابق أيًا من الأحرف المحددة. على سبيل المثال، يطابق "[abc]" الحرف "a" في كلمة "plat".

[^xyz]
مجموعة الأحرف السلبية. تتطابق مع أي حرف غير مدرج. على سبيل المثال، "[^abc]" تتطابق مع "p" في "plat".

[a-z]
نطاق الأحرف. يطابق أي حرف في النطاق المحدد. على سبيل المثال، يطابق "[a-z]" أي حرف أبجدي صغير بين "a" و "z".

[^m-z]
نطاق الأحرف السلبية. يطابق أي حرف غير موجود في النطاق المحدد. على سبيل المثال، يطابق "[^m-z]" أي حرف غير موجود بين "m" و "z".
\b
يتطابق مع حدود الكلمة، أي الموضع بين كلمة ومسافة. على سبيل المثال، يتطابق "er\b" مع "er" في "lever"، ولكنه لا يتطابق مع "er" في "verb".
\B
يتطابق مع حد لا يمثل كلمة. يتطابق "en*t\B" مع "ent" في "bien entendu".
\d
يتطابق مع حرف يمثل رقمًا. يعادل [0-9].
\D
يطابق حرفًا ليس رقمًا. يعادل [^0-9].
\f
يطابق حرف فاصل الأسطر.
\n
يتطابق مع حرف السطر الجديد.
\r
مكافئ لحرف إرجاع الحامل.
\s
يتطابق مع أي مسافة بيضاء، بما في ذلك المسافة، وعلامة الجدولة، وفاصل الصفحة، وما إلى ذلك. يعادل "[ \f\n\r\t\v]".
\S
يتطابق مع أي حرف غير مسافة. يعادل "[^ \f\n\r\t\v]".
\t
يتطابق مع حرف الجدولة.
\v
يتطابق مع حرف الجدولة الرأسية.
\w
يتطابق مع أي حرف يمثل كلمة ويشمل شرطة سفلية. يعادل "[A-Za-z0-9_]".
\W
يطابق أي حرف لا يمثل كلمة. يعادل "[^A-Za-z0-9_]".

\num
يطابق num، حيث num هو عدد صحيح موجب. يشير إلى التطابقات المخزنة. على سبيل المثال، يطابق "(.)\1" حرفين متتاليين متطابقين.

\n
يتطابق مع n، حيث n هو قيمة هروب ثمانية. يجب أن تتكون قيم الهروب الثمانية من 1 أو 2 أو 3 أرقام. على سبيل المثال، يتطابق كل من "\11" و "\011" مع حرف الجدولة. "\0011" يعادل "\001" و "1". يجب ألا تتجاوز قيم الهروب الثمانية 256. إذا تجاوزت ذلك، يتم أخذ أول رقمين فقط في الاعتبار في التعبير. يسمح باستخدام رموز ASCII في التعبيرات العادية.

\xn
يتوافق مع n، حيث n هي قيمة هروب سداسية عشرية. يجب أن تتكون قيم الهروب السداسية العشرية من رقمين. على سبيل المثال، "\x41" يتوافق مع "A". "\x041" يعادل "\x04" و "1". يسمح باستخدام رموز ASCII في التعبيرات العادية.

قد يظهر عنصر في نمط مرة واحدة أو عدة مرات. لنلقِ نظرة على بعض الأمثلة التي تتضمن الرمز \d، الذي يمثل رقمًا واحدًا:

النمط
المعنى
\d
رقم
\d?
رقم واحد أو صفر
\d*
0 أو أكثر من رقم
\d+
رقم واحد أو أكثر
\d{2}
رقمان
\d{3,}
3 أرقام على الأقل
\d{5,7}
بين 5 و 7 أرقام

الآن لنتخيل نموذجًا قادرًا على وصف التنسيق المتوقع لسلسلة:

السلسلة المستهدفة
النمط
تاريخ بتنسيق يوم/شهر/سنة
\d{2}/\d{2}/\d{2}
وقت بتنسيق hh:mm:ss
\d{2}:\d{2}:\d{2}
عدد صحيح غير موقّع
\d+
سلسلة من المسافات، قد تكون فارغة
\s*
عدد صحيح غير موقّع قد يسبقه أو يتبعه مسافات
\s*\d+\s*
عدد صحيح قد يكون موقّعًا ويسبقه أو يتبعه مسافات
\s*[+|-]?\s*\d+\s*
عدد حقيقي غير موقّع قد يسبقه أو يتبعه مسافات
\s*\d+(.\d*)?\s*
عدد حقيقي قد يكون موقّعًا ويسبقه أو يتبعه مسافات
\s*[+|]?\s*\d+(.\d*)?\s*
سلسلة تحتوي على كلمة "just"
\bjuste\b
  

يمكنك تحديد المكان الذي تريد البحث فيه عن النمط في السلسلة:

النمط
المعنى
^النمط
يبدأ النمط السلسلة
النمط$
ينهي النمط السلسلة
^النمط$
يبدأ النمط السلسلة وينهيها
النمط
يتم البحث عن النمط في أي مكان في السلسلة، بدءًا من البداية.
سلسلة البحث
النمط
سلسلة تنتهي بعلامة تعجب
!$
سلسلة تنتهي بنقطة
\.$
سلسلة تبدأ بالتسلسل //
^//
سلسلة تتكون من كلمة واحدة، تليها أو تسبقها مسافات اختيارياً
^\s*\w+\s*$
سلسلة تتكون من كلمتين، يمكن أن تسبقها أو تتبعها مسافات
^\s*\w+\s*\w+\s*$
سلسلة تحتوي على كلمة secret
\bsecret\b

يمكن "استخراج" الأنماط الفرعية من نمط ما. وبالتالي، لا يمكننا فقط التحقق من أن سلسلة ما تتطابق مع نمط معين، بل يمكننا أيضًا استخراج العناصر المطابقة للأنماط الفرعية للنمط التي تم وضعها بين قوسين من تلك السلسلة. على سبيل المثال، إذا كنا نقوم بتحليل سلسلة تحتوي على تاريخ بتنسيق dd/mm/yy ونريد أيضًا استخراج العناصر dd و mm و yy من ذلك التاريخ، فسنستخدم النمط (\d\d)/(\d\d)/(\d\d).

4.9.1. التحقق من مطابقة سلسلة نصية لنمط معين

يتم إنشاء كائن Regex على النحو التالي:

Public Sub New(ByVal pattern As String)

يقوم المنشئ بإنشاء كائن "تعبير عادي" من نمط يتم تمريره كمعلمة (pattern). وبمجرد إنشاء نمط التعبير العادي، يمكن مقارنته بسلاسل الأحرف باستخدام طريقة IsMatch:

Overloads Public Function IsMatch(ByVal input As String) As Boolean

تُرجع IsMatch القيمة true إذا كانت سلسلة الإدخال مطابقة لنمط التعبير العادي. فيما يلي مثال على ذلك:


' options
Option Strict On
Option Explicit On 
 
' namespaces
Imports System
Imports System.Collections
Imports System.Text.RegularExpressions
 
Module regex1
 
    Sub Main()
        ' a regular expression template
        Dim modèle1 As String = "^\s*\d+\s*$"
        Dim regex1 As New Regex(modèle1)
        ' compare a copy with the model
        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
 
    ' poster 
    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

Overloads Public Function Matches(ByVal input As String) As MatchCollection

تُرجع مجموعة من العناصر من السلسلة المدخلة التي تتطابق مع النمط، كما هو موضح في المثال التالي:


' options
Option Strict On
Option Explicit On 
 
' namespaces
Imports System
Imports System.Collections
Imports System.Text.RegularExpressions
 
Module regex2
    Sub Main()
        ' several occurrences of the model in the copy
        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
 
    'poster
    Sub affiche(ByVal msg As String)
        Console.Out.WriteLine(msg)
    End Sub
End Module

تحتوي فئة MatchCollection على خاصية Count، وهي عدد العناصر الموجودة في المجموعة. إذا كان results كائن MatchCollection، فإن results(i) هو العنصر i من هذه المجموعة وهو من النوع Match. في مثالنا، results هي مجموعة العناصر الموجودة في السلسلة example3 التي تطابق النمط pattern2، و results(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. استخراج أجزاء من نمط

يمكن "استخراج" مجموعات فرعية من نمط ما. وبالتالي، لا يمكننا فقط التحقق من أن سلسلة ما تتطابق مع نمط معين، بل يمكننا أيضًا استخراج العناصر المطابقة للمجموعات الفرعية للنمط التي تم وضعها بين قوسين من تلك السلسلة. لذا، إذا كنا نقوم بتحليل سلسلة تحتوي على تاريخ بتنسيق dd/mm/yy ونريد أيضًا استخراج العناصر dd و mm و yy من هذا التاريخ، فسنستخدم النمط (\d\d)/(\d\d)/(\d\d). دعونا ندرس المثال التالي:


' options
Option Strict On
Option Explicit On 
 
' namespaces
Imports System
Imports System.Collections
Imports System.Text.RegularExpressions
 
Module regex2
    Sub Main()
        ' capture elements in the model
        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"
        ' model checking
        Dim résultat As Match = regex3.Match(exemplaire4)
        If résultat.Success Then
            ' the copy corresponds to the model
            affiche(("L'exemplaire [" + exemplaire4 + "] correspond au modèle [" + modèle3 + "]"))
            ' display groups
            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
            ' the copy does not correspond to the model
            affiche(("L'exemplaire[" + exemplaire4 + " ne correspond pas au modèle [" + modèle3 + "]"))
        End If
    End Sub
 
    'poster
    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

توجد الميزة الجديدة في مقتطف الشفرة التالي:


        ' model checking
        Dim résultat As Match = regex3.Match(exemplaire4)
        If résultat.Success Then
            ' the copy corresponds to the model
            affiche(("L'exemplaire [" + exemplaire4 + "] correspond au modèle [" + modèle3 + "]"))
            ' display groups
            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

يتم مقارنة السلسلة example4 بنمط regex3 باستخدام طريقة Match. وهذا يعيد كائن Match، كما هو موضح سابقًا. هنا، نستخدم خاصيتين جديدتين لهذه الفئة:

  • Success: تشير إلى ما إذا كانت هناك مطابقة
  • Groups: مجموعة حيث
    • Groups[0] يقابل الجزء من السلسلة الذي يطابق النمط
    • Groups[i] (i>=1) يتوافق مع المجموعة i من الأقواس

إذا كان النوع النتيجة هو Match، فإن results.Groups يكون من النوع GroupCollection و results.Groups[i] يكون من النوع Group. تحتوي فئة Group على خاصيتين نستخدمهما هنا:

  • Value: قيمة كائن Group الذي يحتوي على العنصر المطابق لمحتوى قوس
  • Index: الموضع الذي تم العثور فيه على العنصر في السلسلة التي تم تحليلها

4.9.4. برنامج تدريبي

قد يمثل العثور على التعبير العادي الذي يسمح لنا بالتحقق من مطابقة سلسلة مع نمط معين تحديًا حقيقيًا في بعض الأحيان. يتيح لك البرنامج التالي التدرب على ذلك. يطلب البرنامج نمطًا وسلسلة ثم يشير إلى ما إذا كانت السلسلة تطابق النمط أم لا.


' options
Option Strict On
Option Explicit On 
 
' namespaces
Imports System
Imports System.Collections
Imports System.Text.RegularExpressions
Imports Microsoft.visualbasic
 
Module regex4
    Sub Main()
        ' a regular expression template
        Dim modèle, chaine As String
        Dim regex As Regex = Nothing
        Dim résultats As MatchCollection
        ' the user is asked for models and samples to compare with this one
        Dim terminé1 As Boolean = False
        Do While Not terminé1
            Dim erreur As Boolean = True
            Do While Not terminé1 And erreur
                ' the model is requested
                Console.Out.Write("Tapez le modèle à tester ou fin pour arrêter :")
                modèle = Console.In.ReadLine()
                ' finished?
                If modèle.Trim().ToLower() = "fin" Then
                    terminé1 = True
                Else
                    ' we create the regular expression
                    Try
                        regex = New Regex(modèle)
                        erreur = False
                    Catch ex As Exception
                        Console.Error.WriteLine(("Erreur : " + ex.Message))
                    End Try
                End If
            Loop
            ' finished?
            If terminé1 Then Exit Sub
            ' the user is asked for the specimens to be compared with the model
            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()
                ' finished?
                If chaine.Trim().ToLower() = "fin" Then
                    terminé2 = True
                Else
                    ' we make the comparison
                    résultats = regex.Matches(chaine)
                    ' success?
                    If résultats.Count = 0 Then
                        Console.Out.WriteLine("Je n'ai pas trouvé de correspondances")
                    Else
                        ' the elements corresponding to the model are displayed
                        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))
                            ' sub-elements
                            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
 
    'poster
    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:

Overloads Public Function Split(ByVal ParamArray separator() As Char) As String()

يتم التعامل مع السلسلة على أنها تسلسل من الحقول مفصولة بالأحرف الموجودة في المصفوفة [separator]. والنتيجة هي مصفوفة من هذه الحقول.

فاصل الحقول في السلسلة هو أحد الأحرف الموجودة في مصفوفة الفاصل. تسمح لنا طريقة Split في فئة Regex بتحديد الفاصل بناءً على نمط:

Overloads Public Function Split(ByVal input As String) As String()

يتم تقسيم السلسلة [input] إلى حقول، يتم فصلها بفاصل يطابق نمط كائن Regex الحالي. لنفترض، على سبيل المثال، أن لدينا أسطر في ملف نصي بالشكل field1، field2، ...، fieldn. يتم فصل الحقول بفاصلة، ولكن قد يسبقها أو يتبعها مسافات. لذلك، فإن طريقة Split الخاصة بفئة String غير مناسبة. توفر طريقة RegEx الحل. إذا كان line هو السطر الذي تمت قراءته، فيمكن الحصول على الحقول عن طريق

dim champs() as string=new Regex("s*,\s*").Split(ligne)

كما هو موضح في المثال التالي:


' options
Option Strict On
Option Explicit On 
 
' namespaces
Imports System
Imports System.Text.RegularExpressions
 
Module regex5
    Sub Main()
        ' a line
        Dim ligne As String = "abc  , def  , ghi"
        ' a model
        Dim modèle As New Regex("\s*,\s*")
        ' decomposition of line into fields
        Dim champs As String() = modèle.Split(ligne)
        ' display
        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 لقراءة وكتابة الملفات الثنائية. لنفكر في التطبيق التالي. نريد كتابة برنامج يُستدعى على النحو التالي:

// syntaxe pg texte bin
// on lit un fichier texte (texte) et on range son contenu dans un
// fichier binaire
// le fichier texte a des lignes de la forme nom : age
// qu'on rangera dans une structure string, int

يحتوي الملف النصي على المحتوى التالي:

paul : 10
helene : 15
jacques : 11
sylvain : 12

البرنامج كالتالي:


' options
Option Strict On
Option Explicit On 
 
' namespaces
Imports System
Imports System.Text.RegularExpressions
Imports System.IO
 
' BinaryWriter()
 
Module bw1
    ' syntax pg text bin
    ' read a text file (text) and store its contents in a
    ' binary file
    ' the text file has lines of the form name: age
    ' which will be stored in a string structure, int
 
    Sub Main(ByVal arguments() As String)
        ' you need 2 arguments
        Dim nbArgs As Integer = arguments.Length
        If nbArgs <> 2 Then
            Console.Error.WriteLine("syntaxe : pg texte binaire")
            Environment.Exit(1)
        End If
        ' open text file in read mode
        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
        ' open binary file for writing
        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
        ' read text file - write binary file
        ' text file line
        Dim ligne As String
        ' line field separator
        Dim séparateur As New Regex("\s*:\s*")
        ' the age model
        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
            ' empty line?
            If ligne.Trim() = "" Then
                traitementFini = True
            End If
            ' one more line
            If Not traitementFini Then
                numLigne += 1
                ' one line name: age
                champs = séparateur.Split(ligne)
                ' we need 2 fields
                If champs.Length <> 2 Then
                    Console.Error.WriteLine(("La ligne n° " & numLigne & " du fichier " & arguments(0) & " a un nombre de champs incorrect"))
                    ' next line
                    traitementFini = True
                End If
            End If
            If Not traitementFini Then
                ' the second field must be an integer >=0
                If Not modAge.IsMatch(champs(1)) Then
                    Console.Error.WriteLine(("La ligne n° " & numLigne & " du fichier " & arguments(0) & " a un âge incorrect"))
                    ' next line
                    traitementFini = True
                End If
                ' write data to the binary file
                output.Write(champs(0))
                output.Write(Integer.Parse(champs(1)))
            End If
            'next line
            ligne = input.ReadLine()
        End While
        ' closing files
        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 للوصول للكتابة إلى الملف
  • عملية الكتابة

                ' on écrit les données dans le fichier binaire
                output.Write(champs(0))
                output.Write(Integer.Parse(champs(1)))

تحتوي فئة BinaryWriter على العديد من طرق Write المُثقلة لكتابة أنواع مختلفة من البيانات البسيطة

  • عملية إغلاق الدفق
        output.Close()

سيتم توفير نتائج التنفيذ السابق بواسطة البرنامج التالي. يقبل هذا البرنامج أيضًا حجتين:

    ' syntaxe pg bin texte
    ' on lit un fichier binaire bin et on range son contenu dans un fichier texte (texte)
    ' le fichier binaire a une structure string, int
    ' le fichier texte a des lignes de la forme nom : age

لذلك، فإننا نقوم بالعملية العكسية. نقوم بقراءة ملف ثنائي لإنشاء ملف نصي. إذا كان الملف النصي الناتج مطابقًا للملف الأصلي، فسنعرف أن التحويل من نصي إلى ثنائي ثم إلى نصي قد نجح. فيما يلي الكود:


' options
Option Strict On
Option Explicit On 
 
' namespaces
Imports System
Imports System.Text.RegularExpressions
Imports System.IO
 
Module br1
    ' syntax pg bin text
    ' read a binary bin file and store its contents in a text file (text)
    ' the binary file has a structure string, int
    ' the text file has lines of the form name: age
 
    Sub Main(ByVal arguments() As String)
        ' you need 2 arguments
        Dim nbArgs As Integer = arguments.Length
        If nbArgs <> 2 Then
            Console.Error.WriteLine("syntaxe : pg binaire texte")
            Environment.Exit(1)
        End If
        ' open binary file for reading
        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
        ' open text file for writing
        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
        ' read binary file - write text file
        Dim nom As String        ' name of a person
        Dim age As Integer        ' his age
        ' binary file evaluation loop
        While True
            ' read name
            Try
                nom = dataIn.ReadString()
            Catch
                ' end of file
                Exit Sub
            End Try
            ' age reading
            Try
                age = dataIn.ReadInt32()
            Catch
                Console.Error.WriteLine("Le fichier " & arguments(0) + " ne semble pas avoir un format correct")
                Exit Sub
            End Try
            ' writing to text file
            dataOut.WriteLine(nom & ":" & age)
            System.Console.WriteLine(nom & ":" & age)
        End While
        ' we close everything
        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 للوصول للقراءة إلى الملف
  • عملية القراءة
                nom = dataIn.ReadString()
                age = dataIn.ReadInt32()

توفر فئة BinaryReader طرق ReadXX متنوعة لقراءة أنواع مختلفة من البيانات البسيطة

  • عملية إغلاق الدفق
        dataIn.Close()

إذا قمنا بتشغيل البرنامجين بالتسلسل، بتحويل personnes.txt إلى personnes.bin ثم personnes.bin إلى personnes.txt2، نحصل على:

dos>more personnes.txt
paul : 10
helene : 15
jacques : 11
sylvain : 12

dos>more personnes.txt2
paul:10
helene:15
jacques:11
sylvain:12

dos>dir
29/04/2002  18:19                   54 personnes.txt
29/04/2002  18:19                   44 personnes.bin
29/04/2002  18:20                   44 personnes.txt2