القائمة الرئيسية

الصفحات

الأحرف والتعابير النمطية في جافا

مفهوم الأحرف

أحرف: تعني characters في اللغة الإنجليزية, و نحن عادةً ما نستخدم أنواع البيانات البدائية ( أي الـprimitive ) لتخزين الأحرف.
أي لتعريف متغير بهدف تخزين حرف, نعرفه كـ char أو int إذا كنا سنتعامل مع الملفات.

مثال

	  // a يحتوي على الحرف ch هنا المتغير
	  char ch = 'a';

	  // و الذي يعتبر حرف Ω يحتوي على الرمز unicode هنا المتغير
	  char unicode = '\u03A9';

	  // هنا قمنا بتعريف مصفوفة من الأحرف
	  char[] charArray = { 'a', 'b', 'c', 'd', 'e' }; 
	

أحياناً يضطر المبرمج أن يستخدم الكائن للنوع و ليس الشكل البدائي للنوع.
من أجل ذلك, جافا تقدم لنا الكلاس Character الذي يحتوي على مجموعة من الدوال الجاهزة للتعامل مع الأحرف.

لتخزين حرف ككائن من الكلاس Character, يمكنك إنشاء كائن من الكلاس Character و تمرير الحرف الذي تريد تخزينه فيه في الـ Constructor.

مثال

	  Character ch = new Character('a'); 
	

ملاحظة

في بعض الحالات يقوم المترجم في جافا بخلق كائن من الكلاس Character عنا. فمثلاً إذا قمنا بتمرير قيمة بدائية نوعها char في دالة تأخذ النوع object كباراميتر, يقوم المترجم في هذه الحالة بشكل تلقائي بتحويل النوع char للنوع Character , هذه الخاصية تسمى auto-boxing و عملية تحويل النوع لنوع بدائي من جديد تسمى unboxing.

مفهوم الـ Escape Sequences

Escape Sequence تعني مجموعة أحرف متتالية, إذا أتت وراء بعضها فإنها تشكل شيء معين.

لخلق Escape Sequence نستخدم الرمز \.
إذاً, أي حرف مسبوق بالرمز \ هو عبارة عن Escape Sequence و يعني شيء معين في جافا.


في هذه اللائحة وضعنا لك جميع الـ Escape Sequences الموجودين في جافا.

Escape Sequence تعريفه
\t يضيف عدة مسافات في مكان وضعها.
\b يزيل الحرف الموجود قبلها.
\n يجعل المحتوى الذي يأتي بعدها ينزل على سطر جديد.
\r يجعل الكود يبدأ في التنفيذ من عندها.
\f يضع فاصل بين المحتوى (أي تقسم المحتوى).
ملاحظة: لن يظهر لك تأثيرها إلا إذا إستخدمتها مع الملفات.
\' لإضافة الرمز ' في مكان وضعها.
\" لإضافة الرمز " في مكان وضعها.
\u يستخدم لإضافة أي حرف أو رمز من خلال الـ unicode الخاص فيه.

هنا وضعنا مثال لكل Escape Sequence موجود في الجدول.

طريقة إستخدام الرمز \t

الرمز \t يضيف عدة مسافات في مكان وضعها.

مثال

Main.java
		public class Main {

		public static void main(String[] args) {

		System.out.println( "1\t 2\t 3\t 4" );

		}

		}
	  

سنحصل على النتيجة التالية عند التشغيل.

		1  2   3   4
	  

طريقة إستخدام الرمز \b

الرمز \bيزيل الحرف الموجود قبلها.

مثال

Main.java
		public class Main {

		public static void main(String[] args) {

		System.out.println( "abc\bd" );

		}

		}
	  

سنحصل على النتيجة التالية عند التشغيل.

		abd
	  

طريقة إستخدام الرمز \n

الرمز \n يجعل المحتوى الذي يأتي بعدها ينزل على سطر جديد.

مثال

Main.java
		public class Main {

		public static void main(String[] args) {

		System.out.println( "My\nName\nIs\nMhamad" );

		}

		}
	  

سنحصل على النتيجة التالية عند التشغيل.

		My
		Name
		Is
		Mhamad
	  

طريقة إستخدام الرمز \r

الرمز \r يجعل الكود يبدأ في التنفيذ من عندها.

مثال

Main.java
		public class Main {

		public static void main(String[] args) {

		System.out.println( "This text will be removed \r from here it will start printing" );

		}

		}
	  

سنحصل على النتيجة التالية عند التشغيل.

		from here it will start printing
	  

طريقة إستخدام الرمز \'

الرمز \' لإضافة الرمز ' في مكان وضعها.

مثال

Main.java
		public class Main {

		public static void main(String[] args) {

		System.out.println( "I love \'java\' very much" );

		}

		}
	  

سنحصل على النتيجة التالية عند التشغيل.

		I love 'java' very much
	  

طريقة إستخدام الرمز \"

الرمز \" لإضافة الرمز " في مكان وضعها.

مثال

Main.java
		public class Main {

		public static void main(String[] args) {

		System.out.println( "I love \"java\" very much" );

		}

		}
	  

سنحصل على النتيجة التالية عند التشغيل.

		I love "java" very much
	  

طريقة إستخدام الرمز \u

الرمز \u يستخدم لإضافة أي حرف أو رمز من خلال الـ unicode الخاص فيه.

مثال

Main.java
		public class Main {

		public static void main(String[] args) {

		System.out.println( "\u0645\u062d\u0645\u062F" );

		}

		}
	  

سنحصل على النتيجة التالية عند التشغيل.

		محمد
	  

دوال الكلاس Character

الكلاس Character هو كلاس جاهز في جافا, يحتوي على دوال للتعامل مع الأحرف, ذكرنا لك بعضها في هذا الجدول.

الدالة مع تعريفها
public static boolean isLetter(char ch) ترجع true إذا كانت القيمة التي مررناها لها مكان الباراميتر ch عبارة عن حرف.
غير ذلك ترجع false.
شاهد المثال »
public static boolean isDigit(char ch) ترجع true إذا كانت القيمة التي مررناها لها مكان الباراميتر ch عبارة عن رقم.
غير ذلك ترجع false.
شاهد المثال »
public static boolean isWhitespace(char ch) ترجع true إذا كانت القيمة التي مررناها لها مكان الباراميتر ch عبارة عن مسافة فارغة.
غير ذلك ترجع false.
شاهد المثال »
public static boolean isUpperCase(char ch) ترجع true إذا كانت القيمة التي مررناها لها مكان الباراميتر ch عبارة عن حرف كبير.
غير ذلك ترجع false.
شاهد المثال »
public static boolean isLowerCase(char ch) ترجع true إذا كانت القيمة التي مررناها لها مكان الباراميتر ch عبارة عن حرف صغير.
غير ذلك ترجع false.
شاهد المثال »
public static char toUpperCase(char ch) نمرر لها مكان الباراميتر الـ ch حرف صغير, فترجع لنا نفس الحرف و لكن كبير.
شاهد المثال »
public static char toLowerCase(char ch) نمرر لها مكان الباراميتر الـ ch حرف كبير, فترجع لنا نفس الحرف و لكن صغير.
شاهد المثال »
public static String toString(char c) تحول قيمة الباراميتر c لقيمة نوعها String و ترجعها.
شاهد المثال »

تعريفها

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



بناؤها

	public static boolean isLetter(char ch)
  


باراميترات

  • مكان الباراميتر ch نمرر قيمة نوعها char تمثل الحرف الذي نريد فحصه.



قيمة الإرجاع

ترجع true إذا كانت القيمة التي نمررها لها مكان الباراميتر ch عبارة عن حرف.
و ترجع false إذا لم تكن كذلك.



مثال

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  System.out.println( Character.isLetter('a') );     // عبارة عن حرف a لأن true سترجع isLetter() هنا الدالة
	  System.out.println( Character.isLetter('#') );     // لأن # ليس حرف false سترجع isLetter() هنا الدالة
	  System.out.println( Character.isLetter('1') );     // لأن 1 ليس حرف false سترجع isLetter() هنا الدالة

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

	  true
	  false
	  false
	

تعريفها

تستخدم لمعرفة ما إذا كانت قيمة الـ char التي نمررها لها مكان الباراميتر ch عبارة عن رقم أم لا.
ترجع true إذا كانت كذلك. و ترجع false إذا لم تكن كذلك.



بناؤها

	public static boolean isDigit(char ch)
  


باراميترات

  • مكان الباراميتر ch نمرر قيمة نوعها char تمثل الحرف الذي نريد فحصه.



قيمة الإرجاع

ترجع true إذا كانت القيمة التي نمررها لها مكان الباراميتر ch عبارة عن رقم.
و ترجع false إذا لم تكن كذلك.



مثال

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  System.out.println( Character.isDigit('a') );     // ليس رقم a لأن false سترجع isDigit() هنا الدالة
	  System.out.println( Character.isDigit('#') );     // لأن # ليس رقم false سترجع isDigit() هنا الدالة
	  System.out.println( Character.isDigit('1') );     // لأن 1 عبارة عن رقم true سترجع isDigit() هنا الدالة

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

	  false
	  false
	  true
	

تعريفها

تستخدم لمعرفة ما إذا كانت قيمة الـ char التي نمررها لها مكان الباراميتر ch عبارة عن مسافة فارغة أم لا.
ترجع true إذا كانت كذلك. و ترجع false إذا لم تكن كذلك.


ملاحظة

الأشياء التالية كلها تعتبر مسافات فارغة:

  • المسافة العادية (space).

  • المسافة التي نحصل عليها بالنقر على الزر Tab.

  • الرمز \n الذي يستخدم للنزول على سطر جديد.



بناؤها

	public static boolean isWhitespace(char ch)
  


باراميترات

  • مكان الباراميتر ch نمرر قيمة نوعها char تمثل الحرف الذي نريد فحصه.



قيمة الإرجاع

ترجع true إذا كانت القيمة التي نمررها لها مكان الباراميتر ch عبارة عن رقم.
و ترجع false إذا لم تكن كذلك.



مثال

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  System.out.println( Character.isWhitespace('a') );    // ليس مسافة فارغة a لأن false سترجع isWhitespace() هنا الدالة
	  System.out.println( Character.isWhitespace('#') );    // لأن # ليس مسافة فارغة false سترجع isWhitespace() هنا الدالة
	  System.out.println( Character.isWhitespace('1') );    // لأن 1 ليس مسافة فارغة false سترجع isWhitespace() هنا الدالة
	  System.out.println( Character.isWhitespace(' ') );    // لأنه يوجد مسافة فارغة true سترجع isWhitespace() هنا الدالة
	  System.out.println( Character.isWhitespace('\t') );   // تعتبر مسافة فارغة \n لأن true سترجع isWhitespace() هنا الدالة
	  System.out.println( Character.isWhitespace('\n') );   // تعتبر مسافة فارغة \n لأن true سترجع isWhitespace() هنا الدالة

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

	  false
	  false
	  false
	  true
	  true
	  true
	

تعريفها

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



بناؤها

	public static boolean isUpperCase(char ch)
  


باراميترات

  • مكان الباراميتر ch نمرر قيمة نوعها char تمثل الحرف الذي نريد فحصه.



قيمة الإرجاع

ترجع true إذا كانت القيمة التي نمررها لها مكان الباراميتر ch عبارة عن حرف كبير.
و ترجع false إذا لم تكن كذلك.



مثال

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  System.out.println( Character.isUpperCase('a') );
	  System.out.println( Character.isUpperCase('A') );   // عبارة عن حرف كبير A لأن true القيمة isUpperCase() هنا فقط سترجع الدالة
	  System.out.println( Character.isUpperCase('#') );
	  System.out.println( Character.isUpperCase('1') );
	  System.out.println( Character.isUpperCase('\n') );
	  System.out.println( Character.isUpperCase(' ') );

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

	  false
	  true
	  false
	  false
	  false
	  false
	

تعريفها

تستخدم لمعرفة ما إذا كانت قيمة الـ char التي نمررها لها مكان الباراميتر ch عبارة عن حرف صغير أم لا.
ترجع true إذا كانت كذلك. و ترجع false إذا لم تكن كذلك.



بناؤها

	public static boolean isLowerCase(char ch)
  


باراميترات

  • مكان الباراميتر ch نمرر قيمة نوعها char تمثل الحرف الذي نريد فحصه.



قيمة الإرجاع

ترجع true إذا كانت القيمة التي نمررها لها مكان الباراميتر ch عبارة عن حرف صغير.
و ترجع false إذا لم تكن كذلك.



مثال

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  System.out.println( Character.isLowerCase('a') );   // عبارة عن حرف صغير a لأن true القيمة isLowerCase() هنا فقط سترجع الدالة
	  System.out.println( Character.isLowerCase('A') );
	  System.out.println( Character.isLowerCase('#') );
	  System.out.println( Character.isLowerCase('1') );
	  System.out.println( Character.isLowerCase('\n') );
	  System.out.println( Character.isLowerCase(' ') );

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

	  true
	  false
	  false
	  false
	  false
	  false
	

تعريفها

نمرر لها مكان الباراميتر الـ ch حرف صغير, فترجع لنا نفس الحرف و لكن كبير.



بناؤها

	public static char toUpperCase(char ch)
  


باراميترات

  • مكان الباراميتر ch نمرر قيمة نوعها char.



قيمة الإرجاع

إذا قمنا بتمرير حرف صيغر لها مكان الباراميتر ch. ترجع لنا نفس الحرف و لكن كبير.
ملاحظة: إذا كانت قيمة الباراميتر ch لا تعتبر من الأحرف ( مثل $ ) فإنها ترجعها كما هي.



مثال

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  System.out.println( Character.toUpperCase('a') );

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

	  A
	

تعريفها

نمرر لها مكان الباراميتر الـ ch حرف كبير, فترجع لنا نفس الحرف و لكن صغير.



بناؤها

	public static char toLowerCase(char ch)
  


باراميترات

  • مكان الباراميتر ch نمرر قيمة نوعها char.



قيمة الإرجاع

إذا قمنا بتمرير حرف كبير لها مكان الباراميتر ch. ترجع لنا نفس الحرف و لكن صغير.
ملاحظة: إذا كانت قيمة الباراميتر ch لا تعتبر من الأحرف ( مثل $ ) فإنها ترجعها كما هي.



مثال

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  System.out.println( Character.toLowerCase('A') );

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

	  a
	

تعريفها

نمرر لها مكان الباراميتر الـ c فترجع نفس القيمة و لكن كـ String.
الأمر الذي سيسمح لنا بمعاملة الحرف كنص و الإستفادة من دوال الكلاس String.



بناؤها

	public static String toString(char ch)
  


باراميترات

  • مكان الباراميتر c نمرر قيمة نوعها char.



قيمة الإرجاع

ترجع القيمة التي نمررها مكان الباراميتر c كـ String.



مثال

Main.java
	  public class Main {

	  public static void main(String[] args) {

	  System.out.println( Character.toString('1') );
	  System.out.println( Character.toString('a') );
	  System.out.println( Character.toString('A') );

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

	  1
	  a
	  A
	

مفهوم التعابير النمطية

تعابير نمطية: تعني Regular Expressions في البرمجة و تختصر بـ regex أو regexp, و هي عبارة عن نص له معنى محدد.
للدقة أكثر, كل حرف أو رمز نضعه في هذا النص يعني شيء معين.
الـ regex هم أحرف و رموز جاهزة تستخدم للبحث في النصوص بطريقة سهلة جداً, دون الحاجة لكتابة خوارزميات معقدة جداً.

خلاصة: نستخدم الـ regex لوضع شروط أثناء البحث في نص معين. و يمكن إستخدامهم في البحث, التعديل, أو لمعالجة النصوص و البيانات.


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

لإنشاء regex و إستخدامه, إتبع الخطوات التالية:

  1. قم بإنشاء نص يمثل الـ regex.

  2. قم بترجمة هذا النص باستخدام الدالة compile(), ثم قم بتخزين النص المترجم في كائن نوعه Pattern.

  3. قم باستدعاء الدالة matcher() من كائن الـ Pattern على أي نص تريد البحث فيه عن تطابق. ثم قم بتخزين النتيجة التي سترجعها الدالة في كائن نوعه Matcher.


لمعرفة إذا كان النص يحتوي على أحرف هي نفسها لأحرف المقصودة من الـ regex يمكنك إستدعاء الدالة matches() على كائن الـ Matcher و سترجع true في حال كان هناك تطابق.


مثال

import java.util.regex.Matcher;
	  import java.util.regex.Pattern;

	  public class Main {

	  public static void main(String[] args) {

	  // b و ينتهي بالحرف a و هو يعني نص يبدأ بالحرف a*b هنا هو النص regex الـ
	  // Pattern ثم قمنا بتخزينه في كائن نوعه compile() قمنا بتحويله باستخدام الدالة
	  Pattern p = Pattern.compile("a*b");

	  // Matcher ثم قمنا بتخزينه في كائن نوعه aaaaaaaab على النص matcher() قمنا باستدعاء الدالة
	  Matcher m = p.matcher("aaaaaaaab");

	  // regex لمعرفة إذا تم إيجاد نص يطابق الـ Matcher على كائن الـ matches() قمنا باستدعاء الدالة
	  System.out.println( "Result: " + m.matches() );

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

Result: true
	


الكلاسات التي تستخدم للتعامل مع التعابير النمطية

هناك إثنين كلاس يستخدمان للتعامل مع الـ regex و هما : Pattern - Matcher


الكلاس Pattern

هذا الكلاس يستخدم لتحويل كائن نوعه String ( عبارة عن regex ) إلى كائن نوعه Pattern.
إذاً كائن الـ Pattern يمثل الحرف أو الأحرف المقصودة من الـ regex.
هذا الكلاس لا يحتوي على كونستركتور.
لإنشاء Pattern, عليك استدعاء واحدة من دواله الثابتة و هي الدالة compile(), و تمرير regex لها كـ argument, و هكذا سترجع كائن نوعه Pattern يمثل regex يفهمها المترجم و جاهزة للإستخدام.


الكلاس Matcher

هذا الكلاس يستخدم لمقارنة الأحرف المقصودة من كائن الـ Pattern مع نص معين.
هذا الكلاس لا يحتوي على كونستركتور.
لإنشاء كائن من الكلاس Matcher, عليك استدعاء الدالة matcher(), على كائن من الكلاس Pattern و تمرير String لها كـ argument, هذه الـ String تمثل النص الذي سيتم البحث فيه عن أحرف تتطابق مع أحرف كائن الـ Pattern.
إذاً كائن الـ Matcher هو الذي ينفذ عمليات المقارنة بين الـ regex و النص.

الأحرف المستخدمة في التعابير النمطية

Regex إستخدامه
"" تعني نص عادي
مثال: "this is just a text".

معناه: إبحث عن نفس هذا النص.
^ تعني بداية السطر
$ تعني نهاية السطر
. تعني أي حرف موجود ما عدا الحرف الذي يشير لسطر جديد.
ملاحظة: يمكن استخدام الحرف m حتى يتم تجاهل الذي يشير لسطر جديد.
[...] تعني أي حرف من الأحرف الموجودة بين المربعين

مثال: "[abc]".
معناه: إبحث عن الحرف a أو b أو c.
[^...] تعني أي حرف غير الأحرف الموجودة بين المربعين

مثال: "[^abc]".
معناه: إبحث عن أي حرف غير الأحرف a أو b أو c.
\A تعني بداية النص
\z تعني نهاية النص
\Z تعني نهاية النص, و إذا كان النص يحتوي على أكثر من سطر, فإنها توقف عملية البحث عن تطابق في نهاية أول سطر.
\b تعني مجموعة أحرف تمثل كلمة أو رقم لا يوجد بينها مسافة أو رمز, في حال لم يتم وضعها بين [ ]
\B تعني ليس كلمة, أي حرف أو رقم واحد. و هي عكس الـ \b
\w تعني مجموعة أحرف تمثل كلمة أو رقم لا يوجد بينها مسافة أو رمز. و هي نفسها [a-zA-Z_0-9]
\W تعني ليس كلمة, أي حرف أو رقم واحد. و هي نفسها [^\W]
\h تعني أن الحرف يمثل مسافة فارغة بشكل أفقي, أي مثل مسافة فارغة بين الكلمات. و هي نفسها [\t\xA0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000]
\H تعني أن الحرف ليس مسافة فارغة. و هي نفسها [^\h]
\s تعني أن الحرف يمثل مسافة فارغة. و هي نفسها [\t\n\x0B\f\r]
\S تعني أن الحرف ليس مسافة فارغة. و هي نفسها [^\S]
\v تعني أن الحرف يمثل مسافة فارغة بشكل عامود, أي يجعل النص ينزل على سطر جديد. و هي نفسها [\n\x0B\f\r\x85\u2028\u2029]
\V تعني أن الحرف لا يمثل مسافة فارغة بشكل عامود. و هي نفسها [^\v]
\d تعني أي رقم. و هي نفسها [0-9]
\D تعني ليس رقم. و هي نفسها [^0-9]
\G تعني نهاية التطابق السابق
\R تعني أي حرف يفصل سلسلة الأحرف عن بعضها. و هي نفسها [\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]
\n تعني حرف يجعل النص ينزل على سطر جديد. و هي نفسها ('\u000A')
\r تعني جعل النص يبدأ من بداية السطر. و هذا الحرف يمثل \r\n. و هي نفسها ('\u000D')
* لتكرار الشيء الذي قبلها من صفر ( أي حتى لو لم يكن هناك شيء أصلاً ) إلى ما لا نهاية.
و هي تستخدم للبحث عن تطابق يبدأ بحرف معين و ينتهي بحرف معين دون الإهتمام إذا كان يحتوي على شيء بين هذين الحرفين أم لا.
+ لتكرار الشيء الذي قبلها مرة أو أكثر
? لتكرار الشيء مرة واحدة أو لا مرة.
| تعني ( أو ) و هي تستخدم لوضع إحتمالات.

مثال: "a|b".
معناه: إبحث عن الحرف a أو b.
() تعني مجموعة, و تستخدم لإنشاء regex ترجع محتوى النص المتطابق مع الـ Pattern الذي تم إيجاده كمجموعة
{n,} لتكرار الشيء الذي قبلها بقيمة العدد الذي نضعه مكان الحرف n.

مثال: "\d{4}".
معناه: إبحث عن عدد يتألف من 4 أرقام.
{n, m} لتكرار الشيء الذي قبلها بقيمة بقيمة محصورة بين m و n.

مثال: "\d{2,4}".
معناه: إبحث عن عدد يتألف من 2 إلى 4 أرقام كحد أقصى.

إنتبه

الرمز \ يسمى backslash, و هو escape character أي حرف له معنى خاص في جافا.
يجب أن تضع \\ لتعريف \. فمثلاً لتعريف \w نكتب \\w.
في الـ regex يجب أن تضع \\\\ لتعريف \ يفهم على أنه escape character.

دوال الكلاس Matcher

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


سنقسم دوال الكلاس Matcher إلى 3 فئات أساسية:

  1. دوال تستخدم لمعرفة إذا تم إيجاد تطابق.

  2. دوال تستخدم لمعرفة الـ index الذي تم فيه إيجاد تطابق.

  3. دوال تستخدم للتبديل.

دوال تستخدم لمعرفة إذا تم إيجاد تطابق

إسم الدالة مع تعريفها
public boolean lookingAt() ترجع true إذا تم إيجاد تطابق بين كائن الـ Pattern و النص الذي نريد البحث فيه.
هذه الدالة تتوقف مباشرةً عن البحث عندما تجد أول تطابق.
public boolean find() ترجع true إذا تم إيجاد أكثر من تطابق بين كائن الـ Pattern و النص الذي نريد البحث فيه.
هذه الدالة تبحث في النص كله من الحرف الأول إلى الحرف الأخير.
أي حتى لو تم إيجاد النص الذي تبحث عنه ستظل تحاول إيجاد تطابق حتى تمر على جميع أحرف النص.
public boolean matches() ترجع true إذا تطابقت جميع أحرف النص مع أحرف كائن الـ Pattern.
أي في حال كان الـ Pattern يطابق كل النص الذي نريد البحث فيه.

وضعنا هنا أمثلة شاملة تعلمك استخدام الدوال المذكورة في الجدول.

شاهد الأمثلة »



إذاً إستخدم الدالة lookingAt() في حال كنت تريد معرفة إذا كان النص يحتوي على حرف, رقم, رمز, كلمة, جملة معينة مرة واحدة.

و استخدم الدالة find() في حال كنت تريد معرفة كم مرة في النص يوجد حرف, رقم, رمز, كلمة, جملة معينة, بالإضافة أنه يمكنك الإستفادة من الدوال start() و end() لمعرفة مكان إيجاد جميع التطابقات في النص.

و استخدم الدالة matches() في حال كنت تريد معرفة إذا كان النص يحتوي على نفس ما يحتويه الـ Pattern.

دوال تستخدم لمعرفة الـ index الذي تم فيه إيجاد تطابق

إسم الدالة مع تعريفها
public int start() ترجع رقم الـ index للحرف الذي بدأ التطابق من عنده.
public int end() ترجع رقم الـ index للحرف الذي إنتهى التطابق عنده.

وضعنا هنا مثال شامل يعلمك استخدام الدوال المذكورة في الجدول.

شاهد المثال »

دوال تستخدم للتبديل

إسم الدالة مع تعريفها
public String replaceAll(String replacement) تقوم بتبديل كل محتوى موجود في النص يتطابق مع محتوى الـ Pattern بمحتوى جديد.
public String replaceFirst(String replacement) تقوم بتبديل أول محتوى موجود في النص يتطابق مع محتوى الـ Pattern بمحتوى جديد.

وضعنا هنا أمثلة شاملة تعلمك استخدام الدوال المذكورة في الجدول.

شاهد الأمثلة »



الجدول التالي يحتوي على دالتين عليك إستدعائهما مع بعض لتنفيذ عملية التبديل.

إسم الدالة مع تعريفها
public Matcher appendReplacement(StringBuffer sb, String replacement) هذه الدالة تبدأ عملية تبديل محتوى محدد في النص كلما وجدته بمحتوى جديد.
فهي تبدل المحتوى الذي تم إيجاده في النص بمحتوى جديد و ترجع النص كله مع التبديل ككائن نوعه StringBuffer.
كما أنها تعتمد على الدوال find() و start() و end() عندما تبحث عن المحتوى الذي سيتم تبديله.
و هي تستفيد من الدوال start() و end() لمعرفة أين يبدأ و أين ينتهي المحتوى الذي سيتم تبديله في النص.
الدالة find() نستخدمها للبحث عن كل تطابق موجود النص.

ملاحظة: الدالة appendReplacement() لا تضيف بقية النص الموجودة بعد آخر مرة تم فيها إيجاد تطابق.
public StringBuffer appendTail(StringBuffer sb) هذه الدالة تكمل عملية تبديل محتوى النص بمحتوى جديد.
هي تقوم فقط بإضافة النص العادي الموجود بعد آخر مرة تم فيها تبديل القيمة.
هذه الدالة تُستدعى بعد إستدعاء الدالة appendReplacement() بالترتيب حتى تضيف باقي المحتوى على الـ StringBuffer.

وضعنا هنا مثال شامل يعلمك استخدام الدوال المذكورة في الجدول.

شاهد المثال »

تقسيم الـ regex إلى مجموعات

تقسيم regex إلى مجموعات هي طريقة لمعالجة عدة أحرف كمجموعة واحدة يتم إنشائهم من خلال وضع الأحرف التي نريد تجميعها بين عدة أقواس.

مثال: الـ regex "dog" هو مجموعة واحدة تتألف من الأحرف "g" , "o" , "d"

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

مثال: في الـ regex "((A)(B(C)))" يوجد أربع مجموعات كما في الصورة التالية:


في مادة الرياضيات يتم رسم هذه المجموعات كما في الصورة التالية:


لمعرفة عدد المجموعات الموجودة في الـ regex, قم باستدعاء الدالة groupCount() على كائن نوعه Matcher.
لاحظ أن group(0) يمثل كل الـ regex الموجود. لذلك الدالة groupCount() لا تضيف الـ group(0) على عدد المجموعات الذي ترجعه.
إذاً هنا إذا قمت بإستدعاء الدالة groupCount() سترجع 3.


مثال

import java.util.regex.Matcher;
	  import java.util.regex.Pattern;

	  public class Main {

	  public static void main(String[] args) {

	  String line = "This order was placed for QT3000! OK?";;   // line: هو النص الذي سنبحث فيه
	  String REGEX = "(.*?)(\\d+)(.*)";                         // REGEX: هو النص الذي سنبحث عنه و سيتم تقسيمه إلى 3 مجموعات

	  Pattern p = Pattern.compile(REGEX);                       // Pattern ثم قمنا بتخزينه في كائن نوعه compile() باستخدام الدالة Pattern إلى REGEX قمنا بتحويل الـ

	  Matcher m = p.matcher(line);                              // Matcher ثم قمنا بتخزينه في كائن نوعه INPUT على النص matcher() قمنا باستدعاء الدالة

	  if ( m.find() )                                           // سيبحث عن التطابق التالي INPUT موجود في الـ Pattern هنا طالما أن الـ
	  {
	  System.out.println( "group 0: " + m.group(0) );       // هنا قمنا بعرض محتوى المجموعة رقم 0 و التي تحتوي على جميع المجموعات
	  System.out.println( "group 1: " + m.group(1) );       // هنا قمنا بعرض محتوى المجموعة رقم 1
	  System.out.println( "group 2: " + m.group(2) );       // هنا قمنا بعرض محتوى المجموعة رقم 2
	  System.out.println( "group 3: " + m.group(3) );       // هنا قمنا بعرض محتوى المجموعة رقم 3
	  }
	  else
	  {
	  System.out.println( "NO MATCH" );                     // سيطبع هذا النص في حال لم يجد أي تطابق
	  }

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

group 0: This order was placed for QT3000! OK?
	  group 1: This order was placed for QT
	  group 2: 3000
	  group 3: ! OK?
	

شرح الكود

Java الدوال lookingAt(), find(), matches()

تعريفهم

lookingAt(): ترجع true إذا تم إيجاد تطابق بين كائن الـ Pattern و النص الذي نريد البحث فيه.
هذه الدالة تتوقف مباشرةً عن البحث عندما تجد أول تطابق.

find(): ترجع true إذا تم إيجاد أكثر من تطابق بين كائن الـ Pattern و النص الذي نريد البحث فيه.
هذه الدالة تبحث في النص كله من الحرف الأول إلى الحرف الأخير.
أي حتى لو تم إيجاد النص الذي تبحث عنه ستظل تحاول إيجاد تطابق حتى تمر على جميع أحرف النص.

matches(): ترجع true إذا تطابقت جميع أحرف النص مع أحرف كائن الـ Pattern.
أي في حال كان الـ Pattern يطابق كل النص الذي نريد البحث فيه.



بناؤهم

                  public boolean lookingAt()

	public boolean find()

	public boolean find(int start) // معين في حال لم ترد البحث من بداية النص index هذا الرقم يستخدم للبحث إبتداءاً من رقم

	public boolean matches() 
  


أخطاء محتملة

  • IndexOutOfBoundsException: في حال وضعنا في الدالة find() رقم index كـ argument, و كان هذا الـ index غير موجود في النص.



المثال الأول

Main.java
                    import java.util.regex.Matcher;
	  import java.util.regex.Pattern;

	  public class Main {

	  public static void main(String[] args) {

	  String REGEX = "java";                                           // REGEX: هو النص الذي سنبحث عنه
	  String INPUT = "java language, java is free, java is amazing";   // INPUT: هو النص الذي سنبحث فيه

	  Pattern p = Pattern.compile(REGEX);   // Pattern ثم قمنا بتخزينه في كائن نوعه compile() باستخدام الدالة Pattern إلى REGEX قمنا بتحويل الـ

	  Matcher m = p.matcher(INPUT);         // Matcher ثم قمنا بتخزينه في كائن نوعه INPUT على النص matcher() قمنا باستدعاء الدالة

	  System.out.println( "lookingAt() \n return: " + m.lookingAt() + "\n" );   // INPUT موجود في النص Pattern لأن محتوى الـ true سترجع lookingAt() هنا الدالة
	  System.out.println( "find() \n return: "      + m.find()      + "\n" );   // INPUT موجود أكثر من مرة في النص Pattern لأن محتوى الـ true سترجع find() هنا الدالة
	  System.out.println( "matches() \n return: "   + m.matches()   + "\n" );   // INPUT لا يساوي كل المحتوى الموجود في النص Pattern لأن محتوى الـ false سترجع matches() هنا الدالة

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

                    lookingAt()
	  return: true

	  find()
	  return: true

	  matches()
	  return: false
	


المثال الثاني

Main.java
                    import java.util.regex.Matcher;
	  import java.util.regex.Pattern;

	  public class Main {

	  public static void main(String[] args) {

	  String REGEX = "welcome to harmash.com";   // REGEX: هو النص الذي سنبحث عنه
	  String INPUT = "welcome to harmash.com";   // INPUT: هو النص الذي سنبحث فيه

	  Pattern p = Pattern.compile(REGEX);   // Pattern ثم قمنا بتخزينه في كائن نوعه compile() باستخدام الدالة Pattern إلى REGEX قمنا بتحويل الـ

	  Matcher m = p.matcher(INPUT);         // Matcher ثم قمنا بتخزينه في كائن نوعه INPUT على النص matcher() قمنا باستدعاء الدالة

	  System.out.println( "lookingAt() \n return: " + m.lookingAt() + "\n" );   // INPUT موجود في النص Pattern لأن محتوى الـ true سترجع lookingAt() هنا الدالة
	  System.out.println( "find() \n return: "      + m.find()      + "\n" );   // INPUT موجود مرة واحدة فقط في النص Pattern لأن محتوى الـ false سترجع find() هنا الدالة
	  System.out.println( "matches() \n return: "   + m.matches()   + "\n" );   // INPUT يساوي كل المحتوى الموجود في النص Pattern لأن محتوى الـ true سترجع matches() هنا الدالة

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

                    lookingAt()
	  return: true

	  find()
	  return: false

	  matches()
	  return: true 
	

Java الدالة start() و الدالة end()

تعريفهم

start(): ترجع رقم الـ index للحرف الذي بدأ التطابق من عنده.

end(): ترجع رقم الـ index للحرف الذي إنتهى التطابق عنده.



بناؤهم

                  public int start()

	public int end()
  


أخطاء محتملة

  • IllegalStateException: في حال تم إستدعاء أي واحدة منهما و لم يكن هناك أي تطابق من الأساس.



مثال

Main.java
                    import java.util.regex.Matcher;
	  import java.util.regex.Pattern;

	  public class Main {

	  public static void main(String[] args) {

	  String REGEX = "java";                                           // REGEX: هو النص الذي سنبحث عنه
	  String INPUT = "java language, java is free, java is amazing";   // INPUT: هو النص الذي سنبحث فيه

	  Pattern p = Pattern.compile(REGEX);   // Pattern ثم قمنا بتخزينه في كائن نوعه compile() باستخدام الدالة Pattern إلى REGEX قمنا بتحويل الـ

	  Matcher m = p.matcher(INPUT);         // Matcher ثم قمنا بتخزينه في كائن نوعه INPUT على النص matcher() قمنا باستدعاء الدالة

	  int count = 0;                        // سنستخدم هذا المتغير لتخزين عدد المرات التي تم فيها إيجاد تطابق

	  while ( m.find() )                    // سيبحث عن التطابق التالي INPUT موجود في الـ Pattern هنا طالما أن الـ
	  {
	  count++;                                         // واحد في كل مرة يتم فيها إيجاد تطابق count هنا قمنا بزيادة الـ
	  System.out.println( "start(): " + m.start() );   // هنا قمنا بطباعة أي بدأ التطابق
	  System.out.println( "end(): " + m.end() );       // هنا قمنا بطباعة أي إنتهى التطابق
	  System.out.println();
	  }

	  System.out.println( "Match number: " +count );       // هنا قمنا بطباعة عدد المرات التي تم فيها إيجاد تطابق

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

                    start(): 0
	  end(): 4

	  start(): 15
	  end(): 19

	  start(): 29
	  end(): 33

	  Match number: 3 
	

هنا أنت مجبر أن تستخدم الدالة find() لأنك تريد معرفة جميع الأماكن التي ظهر فيها تطابق.
لو إستخدمت الدالة lookingAt() بدلاً من الدالة find() لكان البرنامج سيستمر في التنفيذ إلى أن توقفه بنفسك, و كان سيظهر لك فقط أول مكان تم فيه إيجاد تطابق.


ملاحظة: في المثال السابق كان بإمكاننا تعريف المتغير REGEX بهذه الطريقة:

                  String REGEX = "//bjava"; 
  

Java الدالة replaceAll() و الدالة replaceFirst()

تعريفهم

replaceAll(): تقوم بتبديل كل محتوى موجود في النص يتطابق مع محتوى الـ Pattern بمحتوى جديد.

replaceFirst(): تقوم بتبديل أول محتوى موجود في النص يتطابق مع محتوى الـ Pattern بمحتوى جديد.



بناؤهم

                  public String replaceAll(String replacement)

	public String replaceFirst(String replacement)
  


المثال الأول

في هذا المثال قمنا باستخدام الدالة replaceAll() لتبديل كل كلمة dog يتم إيجادها في النص بالكلمة cat.

Main.java
                    import java.util.regex.Matcher;
	  import java.util.regex.Pattern;

	  public class Main {

	  public static void main(String[] args) {

	  String REGEX = "dog";                                                     // REGEX: هو النص الذي سنبحث عنه
	  String INPUT = "I have one dog, my friend have two dogs and one bird.";   // INPUT: هو النص الذي سنبحث فيه

	  Pattern p = Pattern.compile(REGEX);     // Pattern ثم قمنا بتخزينه في كائن نوعه compile() باستخدام الدالة Pattern إلى REGEX قمنا بتحويل الـ

	  Matcher m = p.matcher(INPUT);           // Matcher ثم قمنا بتخزينه في كائن نوعه INPUT على النص matcher() قمنا باستدعاء الدالة

	  INPUT = m.replaceAll("cat");            // INPUT ثم قمنا بتخزينه في النص cat بالكلمة Pattern يتطابق مع محتوى الـ INPUT هنا قمنا بتبديل كل محتوى موجود في النص

	  System.out.println( INPUT );            // بعد أن تمت عملية التبديل INPUT هنا قمنا بعرض قيمة النص

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

                    I have one cat, my friend have two cats and one bird.
	


المثال الثاني

في هذا المثال قمنا باستخدام الدالة replaceFirst() لتبديل أول كلمة dog يتم إيجادها في النص بالكلمة cat.

Main.java
                    import java.util.regex.Matcher;
	  import java.util.regex.Pattern;

	  public class Main {

	  public static void main(String[] args) {

	  String REGEX = "dog";                                                     // REGEX: هو النص الذي سنبحث عنه
	  String INPUT = "I have one dog, my friend have two dogs and one bird.";   // INPUT: هو النص الذي سنبحث فيه

	  Pattern p = Pattern.compile(REGEX);     // Pattern ثم قمنا بتخزينه في كائن نوعه compile() باستخدام الدالة Pattern إلى REGEX قمنا بتحويل الـ

	  Matcher m = p.matcher(INPUT);           // Matcher ثم قمنا بتخزينه في كائن نوعه INPUT على النص matcher() قمنا باستدعاء الدالة

	  INPUT = m.replaceFirst("cat");          // INPUT ثم قمنا بتخزينه في النص cat بالكلمة Pattern يتطابق مع محتوى الـ INPUT هنا قمنا بتبديل كل محتوى موجود في النص

	  System.out.println( INPUT );            // بعد أن تمت عملية التبديل INPUT هنا قمنا بعرض قيمة النص

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

                    I have one cat, my friend have two dogs and one bird.
	

Java الدالة appendReplacement() و الدالة appendTail()

تعريفهم

appendReplacement(): هذه الدالة تبدأ عملية تبديل محتوى محدد في النص كلما وجدته بمحتوى جديد.
فهي تبدل المحتوى الذي تم إيجاده في النص بمحتوى جديد و ترجع النص كله مع التبديل ككائن نوعه StringBuffer.
كما أنها تعتمد على الدوال find() و start() و end() عندما تبحث عن المحتوى الذي سيتم تبديله.
و هي تستفيد من الدوال start() و end() لمعرفة أين يبدأ و أين ينتهي المحتوى الذي سيتم تبديله في النص.
الدالة find() نستخدمها للبحث عن كل تطابق موجود النص.
ملاحظة: الدالة appendReplacement() لا تضيف بقية النص الموجودة بعد آخر مرة تم فيها إيجاد تطابق.

appendTail(): هذه الدالة تكمل عملية تبديل محتوى النص بمحتوى جديد.
هي تقوم فقط بإضافة النص العادي الموجود بعد آخر مرة تم فيها تبديل القيمة.
هذه الدالة تُستدعى بعد إستدعاء الدالة appendReplacement() بالترتيب حتى تضيف باقي المحتوى على الـ StringBuffer.



بناؤهم

                  public Matcher appendReplacement(StringBuffer sb, String replacement)

	public StringBuffer appendTail(StringBuffer sb)
  


أخطاء محتملة

  • IllegalStateException: في حال لم تجد الدالة appendReplacement() أي تطابق في النص, أو في حال حدث خطأ في التطابق السابق.

  • IllegalArgumentException: في حال لم تجد الدالة appendReplacement() الـ Pattern التي تشير لمجموعة.

  • IndexOutOfBoundsException: في حال لم تجد الدالة appendReplacement() الـ Pattern التي تشير لمجموعة.



مثال

Main.java
                    import java.util.regex.Matcher;
	  import java.util.regex.Pattern;

	  public class Main {

	  public static void main(String[] args) {

	  String REGEX = "dog";                                                     // REGEX: هو النص الذي سنبحث عنه
	  String INPUT = "I have one dog, my friend have two dogs and one bird.";   // INPUT: هو النص الذي سنبحث فيه

	  Pattern p = Pattern.compile(REGEX);     // Pattern ثم قمنا بتخزينه في كائن نوعه compile() باستخدام الدالة Pattern إلى REGEX قمنا بتحويل الـ

	  Matcher m = p.matcher(INPUT);           // Matcher ثم قمنا بتخزينه في كائن نوعه INPUT على النص matcher() قمنا باستدعاء الدالة

	  StringBuffer sb = new StringBuffer();   // لتخزين النص الذي سيحتوي على النسخة التي تم تبديلها StringBuffer قمنا بإنشاء كائن نوعه

	  while ( m.find() )                      // سيبحث عن التطابق التالي INPUT موجود في الـ Pattern هنا طالما أن الـ
	  {
	  m.appendReplacement(sb, "cat");     // هنا بدأنا عملية التبديل
	  }

	  m.appendTail(sb);                       // هنا قمنا بإتمام عملية التبديل

	  System.out.println( sb.toString() );    // sb هنا قمنا بعرض قيمة النص التي تم تبديلها و تخزينها في الكائن

	  }

	  }
	

سنحصل على النتيجة التالية عند التشغيل.

                    I have one cat, my friend have two cats and one bird.
	

شرح الكود

  • هنا كان الهدف تبديل الكلمة dog بالكلمة cat.

  • لو لم تستدعي الدالة appendTail() على الكائن m لكان ظهر محتوى النص الجديد ناقصاً.

  • أي لو قمت بمسح الكود m.appendTail(sb); الموجود في السطر 22, ستحصل على النتيجة التالية عند التشغيل.

  •                         I have one cat, my friend have two cat