تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
التحقق من السلاسل النصية والأرقام والتواريخ
#1
كاتب الموضوع : samerselo



يمكننا استخدام نموذج بحث كنموذج تحقق وذلك بتضمينه ضمن الرموز ^ و $ واستخدام الطريقة IsMatch بدلا من الطريقة Matches فمثلا يتحقق الكود التالي من أن النص يحتوي على خمسة أرقام تمثل رمز منطقة في أمريكا

كود :
pattern = "^\d{5}$"
If Regex.IsMatch(Text, pattern) Then
' It's a string containing five digits.
End If
وهنا ستصبح الأمور أكثر إثارة عندما تريد استبعاد بعض التراكيب من مجموعة النصوص الصحيحة الشئ الذي يمكنك فعله بواسطة التركيب (?!) فعلى سبيل المثال التسلسل 00000 لا يعتبر رمز منطقة صالح حيث يمكنك استبعاده كالتالي

كود :
pattern = "^(?!00000)\d{5}$"
يمكنك استخدام تراكيب النظر مقدما (?=) للتأكد من أن نص الإدخال يحتوي على جميع المحارف ضمن فئة معطاة بغض النظر عن مكانها فمثلا يمكنك استخدام التركيب التالي لفرض سياسة كلمة سر قوية والتأكد من أن مستخدم البرنامج يقوم بإدخال ثمانية محارف كحد أدنى وأنها تحتوي على أرقام وحروف كبيرة وصغيرة

كود :
pattern = "^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])\w{8,}$"
دعنا نرى كيف يعمل هذا التركيب. الشرط الأول (?=.*\d) يجعل البحث يفشل منذ البداية إذا كان جزء النص على يمينه لا يحتوي على أرقام والتركيب (?=.*[a-z]) يتأكد أن النص المدخل يحتوي على حروف صغيرة وبالمثل التركيب (?=.*[A-Z]) يتأكد من احتواء النص على حروف كبيرة. وتراكيب النظر للأمام هذه لا تستهلك أية محارف وبهذا يتأكد التركيب \w{8,} المتبقي من أن النص يحتوي على ثمانية محارف كحد أدنى

ويظهر في التحقق من رقم في مجال معطى مشاكل مثيرة وبشكل عام قد تريد استخدام التعابير النظامية للتحقق من الأرقام والتواريخ لأن النوع DateTime يزودك بالطرق Parse و Try-Parse وجميع الأنواع الرقمية أيضا مما يوفر مرونة أكثر ومع ذلك في بعض الحالات تكون التعابير النظامية قابلة للتطبيق حتى في هذه المهمة فمثلا قد تريد استخراج الأرقام والتواريخ الصحيحة من وثيقة أطول والتأكد من أن العدد الصحيح Integer يملك قيمة حتى حد معين تعتبر مشكلة عادية بالطبع

كود :
' Validate an integer in the range of 0 to 9,999; accept leading zeros.
pattern = "^\d{1,4}$"
تركيب النظر للأمام (?!) السلبي يجعلك تتحكم بعدة حالات

كود :
' Validate an integer in the range 1 to 9,999; reject leading zeros.
pattern = "^(?!0)\d{1,4}$"

' Validate an integer in the range 0 to 9,999; reject leading zeros.
' (Same as previous one, but accept a single zero as a special case.)
pattern = "^(0|(?!0)\d{1,4})$"
إذا كان الحد الأدنى للمجال المقبول ليس بالصيغة 99…999 تبقى لديك إمكانية استعمال التعابير النظامية لعمل التحقق ولكن التركيب يصبح أكثر تعقيدا فمثلا يتحقق التركيب التالي من أن الرقم ضمن المجال من 0 إلى 255 بدون أصفار سابقة

كود :
pattern = "^(25[0–5]|2[0–4]\d|1\d\d|[1–9]\d|\d)$"
التركيب 25[0-5] يتحقق من الأرقام في المجال من 250 إلى 255 والتركيب 2[0-4]\d يتحقق من الأرقام ضمن المجال من 200 إلى 249 والتركيب 1\d\d يتحقق من الأرقام ضمن المجال من 100 إلى 199 والتركيب [1-9]\d يهتم بالأرقام من 10 إلى 99 وأخيرا التركيب \d يغطي المجال من 0 إلى 9 وبتعديل بسيط على التركيب يمكنك التحقق من رقم IP مكون من أربعة أقسام مثل 192.168.0.11

كود :
pattern = "^((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}" _
& "(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)$"
وتصبح الأمور أكثر تعقيد بسرعة ضمن المجالات الأكبر

كود :
' Validate an integer number in the range 0 to 65,535; leading zeros are OK.
pattern = "^([1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-4]|\d{1,4})$"
وقد يكون للأرقام إشارة تسبقها تحتاج لمعالجة خاصة

كود :
' Validate an integer in the range -32,768 to 32,767; leading zeros are OK.
pattern = "^(-?[12]\d{4}|-?3[0-1]\d{3}|-?32[0-6]\d{2}|-?327[0-5]\d|" _
& "-?3276[0-7]|-32768|-?\d{1,4})$"
لاحظ في التركيب السابق أن الحالة الخاصة -3278 يجب التعامل معها بشكل مستقل وكل التركيب الباقي يملك إشارة ناقص اختيارية سابقة ويمكنك استخدام تقنية شبيهة للتحقق من قيمة وقت

كود :
' Validate a time value in the format hh:mm; the hour number can have a leading zero.
pattern = "^(2[0–3]|[01]\d|\d):[0–5]\d$"
والتحقق من قيم التاريخ قد تكون أكثر صعوبة بسبب احتواء كل شهر على عدد مختلف من الأيام وفوق كل ذلك يعتمد اليوم الصحيح في شهر شباط على كون السنة كبيسة أم لا وقبل تقديم حل لهذه المشكلة دعنا نرى كيف يمكن للتعابير النظامية التحقق من أن أي رقم معطى ذو خانتين يقبل القسمة على 4

كود :
' If the first digit is even, the second digit must be 0, 4, or 8.
' If the first digit is odd, the second digit must be 2 or 6.
pattern = "^([02468][048]|[13579][26])$"
وباستخدام افتراض مبسط بأن رقم السنة ذو خانتين فقط فسيكون بالتالي التاريخ المعطى في القرن الحالي مما سيمكننا من تبسيط التعبير النظامي بشكل واضح لأن السنة 2000 كبيسة بعكس السنة 1900 و 2100 ولتوضيح التعبير النهائي قسم التركيب إلى أربعة سطور

كود :
' This portion deals with months with 31 days.
Dim p1 As String = "(0?[13578]|10|12)/(3[01]|[012]\d|\d)/\d{2}"
' This portion deals with months with 30 days.
Dim p2 As String = "(0?[469]|11)/(30|[012]\d|\d)/\d{2}"
' This portion deals with February 29 in leap years.
Dim p3 As String = "(0?2)/29/([02468][048]|[13579][26])"
' This portion deals with other days in February.
Dim p4 As String = "(0?2)/(2[0-8]|[01]\d|\d)/\d{2}"
' Put all the patterns together.
pattern = String.Format("^({0}|{1}|{2}|{3})$", p1, p2, p3, p4)
' Check the date.
If Regex.IsMatch(Text, pattern) Then
' Date is valid.
End If
وإن كان رقم السنة ذو خانتين أو أربع خانات وجب علينا الأخذ بعين الاعتبار أنه ليست جميع السنوات القابلة للقسمة على 100 كبيسة إلا إن كانت قابلة للقسمة على 400 مما يجعل التركيب النظامي أكثر تعقيدا ولكنك أصبحت تملك الخبرة الكافية لفهم كيف يعمل الكود التالي

كود :
' This portion deals with months with 31 days.
Const s1 As String = "(0?[13578]|10|12)/(3[01]|[12]\d|0?[1–9])/(\d\d)?\d\d"
' This portion deals with months with 30 days.
Const s2 As String = "(0?[469]|11)/(30|[12]\d|0?[1-9])/(\d\d)?\d\d "
' This portion deals with days 1–28 in February in all years.
Const s3 As String = "(0?2)/(2[0–8]|[01]\d|0?[1–9])/(\d\d)?\d\d"
' This portion deals with February 29 in years divisible by 400.
Const s4 As String = "(0?2)/29/(1600|2000|2400|2800|00)"
' This portion deals with February 29 in noncentury leap years.
Const s5 As String = "(0?2)/29/(\d\d)?(0[48]|[2468][048]|[13579][26])"
' Put all the patterns together.
pattern = String.Format("^({0}|{1}|{2}|{3}|{4})$", s1, s2, s3, s4, s5)
وسيكون من السهل عمل تعبير نظامي للتواريخ من الشكل dd/mm/yy وذلك بالأخذ بعين الاعتبار اختلاف الحرف الفاصل بين أقسام التاريخ.
}}}}
تم الشكر بواسطة:


التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم