REGEX (Regular Expression)

أولا: التعبيرات القياسية :

التعبيرات القياسية مفيدة بشكل كبير خصوصا لو أردت أن يدخل المستخدم بيانات ولكن بقيود معينة ، مثلا البريد الإلكتروني تريده أن يقوم بإدخاله بصيغته الصحيحة كالتالي:

 

Ahmed1431@gmail.com


ثانيا: طريقة التعبير عن التعبيرات القياسية :

لابد من التعرف على الرموز المستخدمة للتعبير عن الرموز القياسية :

d\ :-

مخصص لإدخال رقم من ٠-٩ فقط أي لو قمت بإدخال أي حرف او رمز ستكون النتيجة false .

 

w\:-

لإدخال أي من القيم التالية : a-z ,A-Z ,0-9 الحروف سواء كانت كبيرة أو صغيرة وأي رقم من ٠-٩ .

 

s \:-

لطباعة مسافة .

 

[]:-

للتنسيق بمعنى لو أردت أن تطلب من المستخدم إدخال حروف من a-z ونلاحظ أننا طلبنا حروف صغيرة نقوم بوضعها بين هذه الأقواس المربعة هكذا : [a-z]

 

{ }:-

نستخدمها لتحديد عدد الخانات المدخلة فمثلا بعد طلبك من المستخدم ادخال اسمه سنقوم بتحديد عدد الحروف المدخلة بحيث أن اسمه لا يتجاوز ٢٠ حرف ولا يقل عن ٥ مثلا هكذا :

 [a-z]{5,20}

*\:-

لو أردت أن يقوم المستخدم بإدخال خانات كثيرة وفي حال أيضا تركت له خيار بأن لا يقوم بالإدخال أيضا. مثلا :

\w*

+\:-

لو أردت أن يقوم المستخدم بإدخال خانات كثيرة أو على الأقل لابد من إدخال خانة واحدة بمعنى لا مجال لتركه فاضي إما إن تقوم بملء الفراغ بخانات كثيرة أو على الأقل أدخل خانة. مثلا :

\w+

 

?\:-

يدع المجال للمستخدم إما أن لا يدخل أبدا أو يدخل خانة واحدة فقط ، مثلا :

\w?

 

():-

لتجميع التنسيق الذي تخطط له ، مثلا :

("\d{4}")

نلاحظ أننا وضعنا قوسين دائريين ومن ثم علامة التنصيص.

 

| :-

 

لنفرض أنك طلبت من المستخدم إدخال بيان معين ويحتمل إدخاله أكثر من شكل (تنسيق) فنستخدم هذه العلامة للتخيير بمعنى لو أدخل التنسيق الذي عرفناه أو التنسيق الأخر فهو صحيح، مثلا :

لو طلبت من المستخدم إدخال رقم الهاتف النقال فأنت تتوقع إدخاله بطريقتين إما أن يقوم بإدخال ١٠ ارقام كما هو معتاد أو إما عن طريق وضع مفتاح الدولة ومن ثم ٩ ارقام هكذا :

var exp = Regex("\d{10}")
var exp1 = Regex("\+966\d{9}")

وعند الاختيار سنقوم هكذا :

exp |exp1

 

 

للوصول إلى الرموز كـ (& ، * ، ؟ ، # ، @ ،! ، . ، …إلخ) :-

?\

$\

&\

*\

Dout . :-

تستخدم للتجاهل فمثلا تريد تجاهل خانة أو أكثر في القيمة المدخلة  ، مثلا :

\d..\d{4}

نلاحظ طلبنا أنه يدخل في البداية رقم ثم . لتجاهل خانة و . مرة أخرى لتجاهل خانة ثانية ومن ثم رقم .


ثالثا: مثال :

fun main(args:Array<String>){

      println("Hello , please complete this form :\n Enter your name :")
      val nameEx = Regex("\w{3,10}\s\w{3,15}")
      val name = readLine()!!.toString()
      if(nameEx.matches(name)){
            println(" Enter your phone number :")
            val phoneEx = Regex("\+966\d{9}")
            val phone = readLine()!!.toString()
            if(phoneEx.matches(phone)){
                  println(" Enter your Email :")
                  val emailEx = Regex("(^[a-zA-Z0-9_.+-]{2,25}+@[a-zA-Z0-9-]{5,12}+\.[a-zA-Z0-9-.]{2,3})")
                  val email = readLine()!!.toString()
                  if(emailEx.matches(email)){
                        println("thank you")
                  }
                  else {
                        println("please enter correct email")
                  }
            }
            else {
                  println("please enter correct phone name begining with +966 ")
            }
      }
      else {
            println("please enter correct name")
      }
}

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

Hello , please complete this form :
Enter your name :
ahmed aljuaid
Enter your phone number :
+966123456789
Enter your Email :
ahmed12.ahmed@gmail.com
thank you

 


رابعا: الدوال المستخدمة مع التعبيرات القياسية :

  • Find :-

القيمة العائدة [matchedResult – null] .

تتحقق هذه الدالة من تطابق النص المدخل مع التنسيق المخصص له طالما كان متطابق يعود بالقيمة المدخلة ، وعند عدم التطابق يعود بـ null .

 

مثال :-

println("enter your phone number:")
var phone = readLine()!!.toString()

val phoneEx :String? = Regex("\+966\d{9}")  // like : +966561234567
        .find(phone)?.value
println(phoneEx)

 

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

ادخلنا قيمة غير مطابقة للتنسيق فنلاحظ انه سيطبع null .

 

 

 

  • findAll :-

القيمة العائدة : تعود بجميع القيم المتطابقة مع التنسيق المطلوب .  مثلا :-

val matchedResults = Regex(pattern = """\d+""").findAll(input = "1as232v4")

for (i in matchedResults) {
    print(i.value + " ")
}

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

التنسيق المطلوب في المثال هو رقم فقط فنقوم بعمل حلقة تعود بالأرقام الموجودة في النص مع طباعة مسافة :-

1 232 4

نلاحظ أنه طبع رقم ١ ومن ثم مسافة ومن ثم طبع الأرقام ٢٣٢ متتالية بدون مساحة لأنها في النص أتت مع بعضها لم يفصلها حرف أو رمز ومن ثم مساحة وهكذا يستمر عملها .

 

 

 

  • matchEntire :-

القيمة العائدة : [matchedResult – null] .

للتحقق من القيمة المدخلة عند التطابق مع التنسيق المخصص له طالما كان متطابق يعود بالقيمة المدخلة ، وعند عدم التطابق يعود بـ null ، مع التنويه أن المسافة تحتسب كحرف فعند إذٍ تعود بـ null لو كان التنسيق المطلوب رقم فقط .

println("enter your age:")

val  age= Regex("\d+").matchEntire("25")?.value

println(age)

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

عند التطابق طبع العمر وعند الاختلاف يعود null .

enter your age:
25

 

 

 

  • matches :-

القيمة العائدة : [true – false] .

للتحقق من تطابق القيمة المدخلة كاملة مع التنسيق المخصص له طالما كان متطابق يعود بـ true ، وعند عدم التطابق يعود بـ false.

 

مثال :-

val regex = Regex(pattern = """\d+""")
println(regex.matches(input = "50 dollars"))

 

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

false

 

 

 

  • containsMatchIn :-

القيمة العائدة : [true – false] .

إذا كان جزء من  القيمة المدخلة متطابقة مع التنسيق المخصص له يعود بـ true ، وعند عدم التطابق يعود بـ false ، وهي عكس الدالة matchEntire التي تعد أن القيمة غير متطابقة.

 

مثال :-

var age =Regex("""\d+""").containsMatchIn("25 years")
println(age)

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

true

نلاحظ أنه عاد بـ true وذلك لأن الوظيفة الرئيسية ليست تطابق جميع القيمة المدخلة إنما يتحقق هل أدخلت رقم كما هو مطلوب في التنسيق .

 

 

  • split :-

القيمة العائدة : تعيد لنا قائمة تخلو من التنسيق الذي أنت حددته . مثال :-

println("enter your age:")
var testSplit = readLine()!!.toString()
val a = Regex("[a-zA-Z]").split(testSplit)
println(a)

طلبنا منه أن يعود بجميع ما تقوم بإدخاله باستثناء Regex(“[a-zA-Z]”) جميع الحروف لا تعود .

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

enter your age:
28
[28]

 

 

 

  • replace :-

القيمة العائدة : القيمة النصية مع استبدال ما تم تحديده في التنسيق من حرف او رقم او رمز بقيمة أخرى .  مثال :-

val testReplace = Regex("""\d+""").replace("ab12cd34ef", "x")
println(testReplace)

 

نلاحظ أن Regex(“””\d+”””)حددنا أننا نريد استبدال كل رقم في النص  replace(“ab12cd34ef”, “x”) حددنا ومن ثم حددنا الحرف الذي نريده أن يحل مكان الرقم الذي نريد تبديله .

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

 

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

abxcdxef