الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

سلسلة تعلم Regular Expressions

مغلق
بدأه الشهاب الحارق في 15 أبريل 2005 · 2 رد · 2,018 مشاهدة · في Microsoft Visual Basic.NET
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

الدرس الحادي عشر والأخير : System.Text.RegularExpressions

مدة الدرس 30 دقيقة .

في الدرس الأخير يتوجب علينا توظيف القوالب والسلوكيات المتوفرة في VB.NET لتكون خاتمة لهذه السلسلة المتواضعه

فسنستهل حديثنا عن القالب Capture Class وهو يقوم بما تقوم به الأداة $ التي تم التطرق لها في الدرس الثامن

وهي عملية حفظ ما تطابق في المجموعة Group , إلا أنه يمتلك إلى خصائص وسلوكان تمكننا بسهولة التعامل مع المجموعات وقيمها.

كل خصائص هذا القالب هي من نوع Read only للقراءة فقط .

يتوجب علينا لتعريف القالب أن نقوم بتعريف مجموعة من نفس النوع وتعرف بـ CaptureCollection وهي كذلك قالب

مستقل بذاته . لنفترض أن لدينا نص بهذا الشكل

one = 1 two = 2 و نريد أن نعرف القيم التي تطابقت من خلال هذه الصيغة وهي

Dim RX As String = "(?<1>\d+)\s*" لنكتب المثال بهذا الشكل

 txt2.Text = "one = 1 two = 2"
        Dim RX As String = "(?<1>\d+)\s*"
        Dim r As New Regex(RX, RegexOptions.IgnoreCase)
        Dim m As Match = r.Match(txt2.Text)
        While m.Success
            Dim cc As CaptureCollection = m.Captures
            Dim c As Capture
            For Each c In cc
                txt3.Text += c.Value()
            Next c
            m = m.NextMatch()
        End While

سيكون الناتج هو 1 و 2 لأننا نبحث عن تطابق أرقام فقط لا كلمات .

يتبين لنا من خلال هذا المثال البسيط أن الفائدة من القالب Capture هو معرفة ما تطابق

من الصيغة وهذا مفيد و مهم جداً لفهم آلية Regex ولمعرفة التطابق بشكل أغزر و أعمق .

القالب Group وهي المجموعة و لها Collection كقالب تعرف بـ GroupCollection

نستطيع اللف فيها و إظهار قيم المجموعات , كذلك نستطيع أن نظهر قيمة مجموعة

دون إستخدام الـ GroupCollection بأن نقوم بالتعامل مع العنصر Match مباشرتاً بهذا الشكل

  txt2.Text = "one=1 two=2"
        Dim RX As String = "\w+=(\d)\s\w+=(\d)"
        Dim r As New Regex(RX, RegexOptions.IgnoreCase)
        Dim m As Match = r.Match(txt2.Text)
        Dim g1 As Group = m.Groups(1)
        Dim g2 As Group = m.Groups(2)
        txt3.Text = "Group 1 is: " & g1.ToString & vbCrLf
        txt3.Text += "Group 2 is: " & g2.ToString

سيكون الناتج في المجموعة الأول القيمة 1 و الثانية القيمة 2

الفائدة القصوى من هذا القالب معرفة قيمة مجموعة معينه كمثلاً المجموعة الأولى أو الثانية

ولهذا يتبين أن الفارق بينه وبين القالب Capture انه يمكن أن يكون خاص و مقيد

بينا Capture هو عام و مطلق .

القالب Match وله كذلك مجموعة تعرف بـ MatchCollection

نستطيع بهذا القالب معرفة هل تم التطابق من عدمه

كذلك نستطيع به أن نقوم بتكرار المطابقة , كما توضح لنا النصوص البرمجية التالية

   Dim m As Match
        Dim rx As New Regex(str2)
        Dim Counter As Integer
        Result = String.Empty
        m = rx.Match(txt2.Text)
        Do While m.Success
            Result += m.Value.ToString & ControlChars.CrLf
            Counter += 1
            m = m.NextMatch
        Loop
        Me.txt3.Text = Result & vbCrLf & " There are " & Counter & " HTML Tags Founded "

التحليل

الخاصية Success ترجع لنا قيمة منطقية أما True أو False وبها

نستطيع معرفة التطابق .

السلوك NextMatch يمكننا من تكرار المطابقة .

كذلك هنالك ما يعرف بـ MatchEvaluator Delegate وهو معلوم لدى الجميع أنه عبارة

عن Function يتم مناداتهِ كلما وقع حدث معين , هذا الـ Delegate مخصص لعملية الإستبدال

Replace , و يتم إستخدامه على النحو التالي

     Dim StrRX, Str As String
        Str = "Arab_Team_Group"
        StrRX = "_"
        Dim rx As Regex = New Regex(StrRX)
        Dim EVl As MatchEvaluator = New MatchEvaluator(AddressOf ReplaceUnderScore)
        Str = rx.Replace(Str, EVl)
        MsgBox(Str)

Public Function ReplaceUnderScore(ByVal m As Match) As String
        Return " "
    End Function

التحليل

أولاً لدينا نص بهذا الشكل Arab_Team_Group

ونريد حذف الـ underscore _ قمنا بتعريف MatchEvaluator

و أسندنا له الإجراء ReplaceUnderScore ليقوم بحذف الـ underscore كلما وجدت عن

طريق الوظيفة Replace بهذا الشكل Str = rx.Replace(Str, EVl)

كذلك نستطيع بدل هذه القصة كلها أن نقوم بالتالي فقط Str = rx.Replace(Str, " ")

ولا نحتاج إلى Delegate لإكمال المهمة .

تكمن فائدة الـ Delegate في التنظيم والترتيب Code Separation And Code Documentation

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

هنالك القالب Regex وهو معلوم لمن تابع هذه السلسلة كونه صميم العمل core

ويتم تعريفه على النحو التالي

       Dim StrRX As String = "^\d.*$"
        Dim rx As Regex = New Regex(StrRX)

هذا القالب لابد أن نقوم بعملية إستنساخ منه بإستخدام الكلمة المحجوزة New ثم أما أن نضع الـ Pattern مباشرةً أو

أن نضع متغير يحوي هذه الصيغة أو الـ Pattern

أو يتم تعريف هذا القالب مع إحدى قيم RegexOptions وهي عبارة عن Enumeration اي قيم معدودة و محصورة .

بهذا الشكل

      rx = New Regex(str5, RegexOptions.None)

خصائص وسلوكيات Regex كالتالي

أولاً القالب Match يقبل النص المراد الإختبار عليه كممرر argument ويعود بقيمة من نوع قالب match

يتم إستخدامه بهذ الشكل

     Result = String.Empty
        Dim m As Match
        Dim rx As New Regex("Color")
        m = rx.Match("What is your Favorite Colour or Color ?")
        Result = m.Value.ToString
        Me.txt3.Text = Result

الوظيفة IsMatch تقبل النص المراد الإختبار عليه كممرر argument و تعود بقيمة منطقية

اما True تم التطابق أو False فشل التطابق , تستخدم بهذا الشكل

     Result = String.Empty
        Dim rx As New Regex("Color")
        Result = rx.IsMatch("What is your Favorite Colour or Color ?")
        Me.txt3.Text = Result

القيمة العائدة في المتغير Result ستكون True وفقاً للمثال هذا .

ثم القالب MatchCollection ذكرنا في الأعلى وهذا مثال أخر عليها .

     Result = String.Empty
        Dim m As Match
        Dim mc As MatchCollection
        Dim rx As New Regex("")
        mc = rx.Matches("What is your Favorite Colour or Color ?", "Colou?r")
        Result = "how many time Matchs called  " & mc.Count
        Me.txt3.Text = Result

النتيجة عدد مرات التطابق ستكون 2 .

وفي هذا القالب كذلك كل من GroupNameFromNumber و GroupNumberFromName لجلب اسماء أو أرقام

المجموعات في الصيغة , بهذا الشكل

      txt2.Text = "a b"
        Dim RX As String = "(?<Group1>A)"
        Dim r As New Regex(RX, RegexOptions.IgnoreCase)
        Dim m As Match = r.Match(txt2.Text)
        Dim g1 As Group = m.Groups(1)
        Dim g2 As Group = m.Groups(2)
        txt3.Text = "Name of Group one is : " & r.GroupNameFromNumber(1).ToString & vbCrLf
        txt3.Text += "The Position of Group1 is : " & r.GroupNumberFromName("Group1").ToString

و البقية تقريباً مررنا عليها من خلال الدروس .

القيم المعدودة هي كالتالي

RegexOptions.None وتعني أنه لا خيار محدد .

RegexOptions.Compiled وتعني أن الـ pattern

يترجم ككل وهذا يأخذ وقت في بدء التشغيل ولكنه أسرع

RegexOptions.CultureInvariant ويعني التعامل مع الـ pattern وفقاً للثقافة لبلدٍ ما.

وهي قيمة حساسة Case sensitive في الـ MSDN الكثير عنها للإطلاع .

RegexOptions.ECMAScript وهي والله أعلم من إسمها أنها تخص الـ J# لانه

ECMA منبع الـ jScript و الـ Action Script و تعني إستخدام نمط البرمجة على نحوها ونصوصها.

RegexOptions.ExplicitCapture وهي عملية إحكام على المجموعات بحيث يتم تجاهل اي مجموعة لا

تحوي اسم أو رقم يميزها عن بقية المجموعات الأخرى. شاهد المثال التالي

       txt2.Text = "one=1 two=2"
        Dim RX As String = "\w+=(?<group1>\d)\s\w+=(?<2>\d)"
        Dim r As New Regex(RX, RegexOptions.ExplicitCapture)
        Dim m As Match = r.Match(txt2.Text)
        Dim g1 As Group = m.Groups(1)
        Dim g2 As Group = m.Groups(2)
        txt3.Text = "Group 1 is: " & g1.ToString & vbCrLf
        txt3.Text += "Group 2 is: " & g2.ToString

النتيجة ستكون 1 & 2

RegexOptions.IgnoreCase هذه القيمة تقوم بتجاهل الحساسية Case sensitive بحيث

يقبل كل من الحروف الصغيرة والكبيرة ولا فرق بينهما من حيث المطابقة . شاهد المثال التالي

       txt2.Text = "a b"
        Dim RX As String = "(?<1>A)\s(?<2>B)"
        Dim r As New Regex(RX, RegexOptions.IgnoreCase)
        Dim m As Match = r.Match(txt2.Text)
        Dim g1 As Group = m.Groups(1)
        Dim g2 As Group = m.Groups(2)
        txt3.Text = "Group 1 is: " & g1.ToString & vbCrLf
        txt3.Text += "Group 2 is: " & g2.ToString

النتيجة ستكون a b رغم أن الـ pattern يحوي A B .

RegexOptions.IgnorePatternWhitespace تقوم بتجاهل الفراغات التي تتخلل ال pattern

كما تقوم بتمكين كتابة التعليقات خلال الصيغة بهذا الشكل

      txt2.Text = "a b "
        Dim RX As String = "(?<1>a)\s(?<2>b)#here is letter b"
        Dim r As New Regex(RX, RegexOptions.IgnorePatternWhitespace)
        Dim m As Match = r.Match(txt2.Text)
        Dim g1 As Group = m.Groups(1)
        Dim g2 As Group = m.Groups(2)
        txt3.Text = "Group 1 is: " & g1.ToString & vbCrLf
        txt3.Text += "Group 2 is: " & g2.ToString

الناتج a و b رغم أن بعد الحرف b يوجد فراغ ولكن تم تجاهله .

كذلك هنالك تعليق بعد المجموعة الثانية بإستخدام الـ #

RegexOptions.Multiline تقوم بتغير نمط ^ بحيث يصبح له معنىً أخر وهو مطابقة بداية النص أو كل مقطع في النص

وينوب عن الأداة (?m)

للمزيد راجع الدرس السادس , ومثاله كالتالي :

      Const str3 As String = "^'.+$"
   Dim m As Match
        Dim rx As New Regex(str3, RegexOptions.Multiline)
        Dim Counter As Integer
        m = rx.Match(txt2.Text)
        Do While m.Success
            Counter += 1
            m = m.NextMatch
        Loop
        MessageBox.Show(" There are " & Counter & " Comments in this String ")

RegexOptions.RightToLeft وتعني بدء المطابقة من اليمين إلى الشمال بالنسبة للنص المراد

إختبار المطابقة عليه وليس الصيغة بذاتها . مثال ذلك

      Result = String.Empty
        Dim m As Match
        Dim rx As Regex
        Select Case whichString
            Case 1
                rx = New Regex(str1)
            Case 2 ' RightToLeft Option let the Regex to Start Matching 
                ' From the Right Side will starts Match the ? then the Color
                rx = New Regex(str2, RegexOptions.RightToLeft)
        End Select
        m = rx.Match(Me.txt2.Text)
        Result = m.Value.ToString
        Me.txt3.Text = Result

RegexOptions.Singleline وهي إرجاع معنى الـ ^ على اساس أنه يقوم بمطابقة أولا النص فقط

وهو عكس RegexOptions.Multiline تماماً وهو كذلك مقدم على الأداة (?m) بحيث لو تم تعريفها في

الصيغة ثم قمنا بإستخدام القيمة SingleLine سيتم إعتماده و تجاهل الأداة (?m) . مثالهُ كالتالي

      Const str3 As String = "(?m)^'.+$"
  Dim m As Match
        Dim rx As New Regex(str3, RegexOptions.Singleline)
        Dim Counter As Integer
        m = rx.Match(txt2.Text)
        Do While m.Success
            Counter += 1
            m = m.NextMatch
        Loop
        MessageBox.Show(" There are " & Counter & " Comments in this String ")

الناتج سيكون تم العثور على تعليق واحد فقط .

أخيراً القالب RegexCompilationInfo نستطيع به معرفة كل من

1. الصيغة ,اي شكل التركيبة المتضمنه فيها.

2. اسم يعنون للصيغة (من حيث الترتيب والتنسيق)

3. هل هو عام أو خاص عن طريق القيمة الأخيرة من هذا القالب أما True أو False

4. معرفة اسم الحاوية NameSpace إذا كنت تضع الصيغ مرتبة في حاويات

5. معرفة نوع الخيار Options الذي يتضمن هذه الصيغة مثل SingleLine أو غير ذلك .

شاهد المثال التالي .

  Dim rxInfo As New RegexCompilationInfo("^\d+$", _
        RegexOptions.Singleline, "CheckNumber", _
         "myNameSpace", True)
        MsgBox(rxInfo.Pattern.ToString())
        MsgBox(rxInfo.Name.ToString())
        MsgBox(rxInfo.IsPublic.ToString())
        MsgBox(rxInfo.Namespace.ToString())
        MsgBox(rxInfo.Options.ToString())

أجوبت الدروس السابقة

الدرس الثاني :

وهنا سؤال يطرح نفسه : في ماذا يستخدم Regex الأداة \ Backslash ؟

يستخدم الـ escaping backslash \ أما لأخطار Regex بأن هذه القيمة نصية وليست أداة أو أن هذا الحرف

أداة وليس حرف فمثلاً \. يراد بها النقطة و . يراد بها خانة واحدة

كذلك \d يراد بها رقم من صفر إلى تسعة و d يراد به حرف الـ d نفسه .

الدرس الثالث :

السؤال الأول : قم ببناء صغية لا تقبل الرقم سبعة 7

[^7]

السؤال الثاني : لو بنينا صيغة بهذا الشكل [A-z]

إضافة إلى الأحرف الكبيرة والصغيرة سيكون كل من [ \ ] ^ _ `

السؤال الثالث والأخير : قم ببناء صغية لا تقبل المسافة , وفقاً لما تعلمناه

Const str1 As String = "^[^ ]$"

الدرس الرابع :

سؤال هذا الدرس : أكتب الصيغة المناسبة لمطابقة القيمة التالية خانة تقبل من واحد إلى عشرة على واحد إلى عشرة

لا تقبل الصفر ولا يمكن أن تكون فارغة . مثلاً 1\10 لكن ليس 0\1 أو Null

"^([1-9]|10)\\([1-9]|10)$"

الدرس الخامس :

1 - yes

2 - yes

3 - yes

4 - No it means single digit or + character

5 - No it's limited to 249 only

6 - No it means single digit and {}

الدرس السادس :

ما هي الأخطاء المرتكبة في هذه التركيبة النصية

  Const str3 As String = "\A'.+\Z"
 Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Dim m As Match
           Dim rx As New Regex(str3, RegexOptions.Singleline)
        Dim Counter As Integer
        m = rx.Match(txt2.Text)
        Do While m.Success
            Counter += 1
            m = m.NextMatch
        Loop
        MessageBox.Show(" There are " & Counter & " Comments in this String ")
    End Sub

الجواب : لا توجد أخطاء مرتكبة في الصيغة .

الدرس السابع :

1 - ^([1-9]{1,2}-){2}[1-9]{1,2}$

2 - ^([1-9]{1,2}-){5}[1-9]{1,2}$ or ^(([1-9]{1,2}-){2}){2}[1-9]{1,2}$

3 - Match the () characters

4 - Wrong Pattren because if you not use ^ at the beginning of the pattren then it means as the repeator tool

for instance ^[1-9]^2$ means repeat digit twice from 1 to 9 matches 11 22 and etc... this concept

does not impact on VB.NET , While Does on Other languages , so What does this pattren mean ?

In VB.NET the ^ tool has several meaning one it matchs the begining of the string or negates mean

if enclosed within [] , so whereas both of them not used then it has wrong meaning

and it acts as the begining Tool in the wrong position. God knows.

الدرس الثامن :

1 - No we use \2

2 - No we either write ?<Nums> or ?'Nums'

3 - No we refer to the Group name by single Qutation 'myGroup'

4 - NO After Starting ( Group

5 - NO we don't need Back Reference

6 - No we use $3

7 - <a([1-6])>.*?</a\1>

الدرس التاسع :

question 1 Answer 3

question 2 Answer 2

question 3 Answer 1

question 4 Answer (?<=<a[1|2|3|4]>).+(?=</a[1|2|3|4]>)

question 5 Answer ^\d{5,6}|(\d{1,6}(?=-)-\d{4})

الدرس العاشر :

Question 1 Answer Wrong the Correct Pattren is (r|h|s)ide

Question 2 Answer Wrong the Correct Pattren is (my|by)

Question 3 Answer Wrong it's Correct pattren with Group and gives Expected Result

Question 4 Answer Wrong it looks for the word Color, RightToLeft Doesn't effect on Pattrens

it effects on the text that the Regex from where it begins to matchs.

Question 5 Answer Wrong the Correct Conditions Tools are ? and |

Question 6 Answer Wrong the Correct Pattren is (my name is :?)

لا توجد أسئلة في هذا الدرس والله يوفقكم لما فيه الخيرو البركة

السلام عليكم .

RegexSetup.zip

في المثال يتضح المقال

#3

مشكووور أخي العزيز وبارك الله فيك

رَبِّ لَا تَذَرْنِي فَرْداً وَأَنتَ خَيْرُ الْوَارِثِينَ

هذا الموضوع مغلق.

مواضيع مشابهة