التعبيرات المنتظمة في جافا: من النظرية إلى التطبيق
\nالتعبيرات المنتظمة (regex) هي أداة قوية للبحث والاستبدال والتحقق من صحة النصوص. في جافا، يتم التعامل معها من خلال حزمة java.util.regex، والتي تتضمن فئتين رئيسيتين: Pattern (النمط) و Matcher(المطابق). في هذه المقالة، سنشرح بناء الجملة والطرق الرئيسية ونعزز المعرفة بأمثلة كود حقيقية.
ستكون المادة مفيدة لكل من المبتدئين الذين يتعرفون على جافا لأول مرة، والمطورين ذوي الخبرة الذين يرغبون في تحديث معلوماتهم. يمكن تشغيل جميع الأمثلة فوراً في بيئة التطوير المتكاملة (IDE) الخاصة بك.
\n\n1. أساسيات العمل مع Pattern و Matcher
\nيبدأ أي عمل مع regex في جافا بتجميع النمط من خلال Pattern.compile(). بعد ذلك، يتم إنشاء كائن Matcher الذي يطبق النمط على السلسلة النصية.
لننظر إلى مثال بسيط: البحث عن جميع الأرقام في النص.
\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\npublic class RegexDemo {\n public static void main(String[] args) {\n String text = "Java الإصدار 21 صدر في عام 2023";\n String regex = "\\\\d+"; // رقم واحد أو أكثر\n\n Pattern pattern = Pattern.compile(regex);\n Matcher matcher = pattern.matcher(text);\n\n while (matcher.find()) {\n System.out.println("تم العثور على: " + matcher.group());\n }\n }\n}\nمخرجات البرنامج:
\nتم العثور على: 21\nتم العثور على: 2023\nلاحظ الشرطة المائلة المزدوجة \\\\d — في جافا، يتطلب النص الحرفي (string literal) الهروب من الخط المائل العكسي. إذا كنت بحاجة إلى تحديد \\d في regex، فاكتب \\\\d في الكود.
2. بناء جملة التعبيرات المنتظمة: الرموز الوصفية والمحددات الكمية
\nلاستخدام regex بفعالية، من المهم تذكر الرموز الوصفية الأساسية:
\n- \n
.— أي حرف (باستثناء فاصل السطر); \n \\\\d— رقم (مكافئ لـ[0-9]); \n \\\\w— حرف أو رقم أو شرطة سفلية ([a-zA-Z0-9_]); \n \\\\s— حرف مسافة بيضاء; \n ^— بداية السطر; \n $— نهاية السطر. \n
تتحكم المحددات الكمية في عدد التكرارات:
\n- \n
+— مرة واحدة أو أكثر; \n *— صفر مرة أو أكثر; \n ?— صفر أو مرة واحدة; \n {n}— n مرة بالضبط; \n {n,m}— من n إلى m مرة. \n
مثال: سنجد جميع الكلمات المكونة من أحرف لاتينية فقط، بطول يتراوح من 3 إلى 5 أحرف.
\nString text = "Java regex example for beginners";\nString regex = "\\\\b[a-zA-Z]{3,5}\\\\b";\n\nPattern pattern = Pattern.compile(regex);\nMatcher matcher = pattern.matcher(text);\n\nwhile (matcher.find()) {\n System.out.println(matcher.group());\n}\n// المخرجات: Java, regex, for\nحد الكلمة \\\\b يمنع التطابق الجزئي (على سبيل المثال، "Java" لن تكون جزءاً من "JavaScript").
3. أمثلة عملية: التحقق من الصحة واستخراج البيانات
\nننتقل إلى المهام التي تظهر غالباً في التطوير الفعلي.
\n\n3.1. التحقق من صحة عنوان البريد الإلكتروني
\nأبسط فحص: وجود الرمز "@" والنطاق.
\npublic static boolean isValidEmail(String email) {\n String regex = "^[\\\\w.-]+@[\\\\w.-]+\\\\.\\\\w{2,}$";\n return Pattern.matches(regex, email);\n}\n\npublic static void main(String[] args) {\n System.out.println(isValidEmail("user@example.com")); // true\n System.out.println(isValidEmail("invalid-email")); // false\n}\nالطريقة Pattern.matches() تتحقق تلقائياً من السلسلة بأكملها (مكافئة لـ matcher.matches()).
3.2. استخراج أرقام الهواتف
\nلنفترض أن النص يحتوي على أرقام بتنسيق "+7 (999) 123-45-67".
\nString text = "جهة الاتصال: +7 (999) 123-45-67 ورقم آخر: +7 (495) 765-43-21";\nString regex = "\\\\+7\\\\s?\\\\(\\\\d{3}\\\\)\\\\s?\\\\d{3}-\\\\d{2}-\\\\d{2}";\n\nPattern pattern = Pattern.compile(regex);\nMatcher matcher = pattern.matcher(text);\n\nwhile (matcher.find()) {\n System.out.println("رقم الهاتف: " + matcher.group());\n}\n// المخرجات:\n// رقم الهاتف: +7 (999) 123-45-67\n// رقم الهاتف: +7 (495) 765-43-21\nهنا نستخدم \\\\s? للإشارة إلى أن المسافة اختيارية، و \\\\d{3} لثلاثة أرقام بالضبط.
3.3. استبدال النص باستخدام regex
\nغالباً ما تكون هناك حاجة ليس فقط للبحث، ولكن أيضاً لاستبدال أجزاء من النص. على سبيل المثال، إخفاء أرقام بطاقات الائتمان.
\nString text = "بطاقتي: 1234 5678 9012 3456";\nString regex = "\\\\d{4}\\\\s\\\\d{4}\\\\s\\\\d{4}\\\\s\\\\d{4}";\n\nString masked = text.replaceAll(regex, "**** **** **** 3456");\nSystem.out.println(masked);\n// المخرجات: بطاقتي: **** **** **** 3456\nالطريقة replaceAll() من فئة String تقبل regex كمعامل أول وسلسلة الاستبدال كمعامل ثانٍ.
4. الأخطاء الشائعة ونصائح للتصحيح
\nحتى المطورين ذوي الخبرة يرتكبون أخطاء عند العمل مع regex. إليك أكثرها شيوعاً:
\n- \n
- نسيان الهروب من الأحرف الخاصة: في جافا، يجب كتابة
\\\\dبدلاً من\\d. \n - عدم مراعاة حالة الأحرف: بشكل افتراضي، regex حساس لحالة الأحرف. استخدم
Pattern.compile(regex, Pattern.CASE_INSENSITIVE)للتجاهل. \n - استخدام
matches()بدلاً منfind(): الأول يتحقق من تطابق السلسلة بأكملها، والثاني يبحث عن تطابق جزئي. \n
نصيحة: استخدم أدوات مثل regex101.com لاختبار التعبيرات قبل كتابتها في الكود.
\n\nالخلاصة
\nالتعبيرات المنتظمة في جافا هي أداة قوية ومرنة. على الرغم من أن بناء الجملة قد يبدو معقداً في البداية، إلا أن الممارسة المنتظمة ستساعدك على إتقانها بسرعة. ابدأ بأمثلة بسيطة، وقم بتعقيد المهام تدريجياً، ولا تنسَ اختبار تعبيراتك على بيانات حقيقية.
\nإذا كان لديك أسئلة أو تريد اقتراح موضوع للمقالة التالية، اكتب في التعليقات! ولا تنسَ الاشتراك في تحديثات المدونة.