من الصفر إلى بطل الـRegex
استخراج وتحليل السلاسل الشبيهة بـ URL باستخدام تعبير نمطي واحد
فهرس المحتويات
- 🚀 المقدمة
- 🔍 استخراج الروابط من النص
- 🛳️ الـ 120+ بايت من Regex
- 🧩 تحليلها خطوة بخطوة
- 🛠️ مثال على التحليل
- ☑️ الخطوات التالية
- 📝 الملخص
- 📚 مزيد من التعلم
TL;DR: انتقل مباشرة إلى الـ 120+ بايت من Regex.
🚀 المقدمة
استخراج الروابط من النص الخام قد يشعر أحيانًا كأنك تلعب لعبة شاقة من “ضرب الفئران”. علامات الترقيم، الأقواس، والتنسيق الغامض كلها تتآمر لتعقّب جهودك. سواءً كنت تبني أداة جمع بيانات ويب، محلل بيانات، أو تطبيق دردشة، فإن استخراج الروابط بدقة أمر أساسي.
في هذه المقالة، سنواجه المشكلة مباشرةً باستخدام نهج مرن من خطوتين. هدفنا هو التقاط جميع السلاسل التي قد تشبه الروابط أولًا ثم التعامل مع التحقق في عملية لاحقة.
💡 ملاحظة: هذا النمط ليس لـ التحقق من صحة الروابط! إنه متساهل عمدًا مع علامات الترقيم والأخطاء الإملائية.
🔍 الهدف: استخراج الروابط من النص
عند استخراج الروابط من النص الخام، يكون النهج ذو الخطوتين فعالًا:
- التقاط كل ما يشبه الرابط: صِدّ شبكة واسعة لالتقاط جميع السلاسل التي قد تكون روابط. هنا يبرز «تعبير regex بحجم 120+ بايت».
- التحقق: بعد أن تلتقط هذه المرشحات، استخدم فحوصًا ثانوية (مثل حل DNS، أو المقارنة مع نطاقات معروفة) لتصفية الإدخالات غير الصالحة.
تصور التحدي
تُستَخدم مصطلحات extract و parse غالبًا بصورة متبادلة، لكنهما تشير إلى عمليتين مميزتين. استخراج الروابط يعني تحديد والتقاط الروابط المحتملة من نص أكبر. أما التحليل (parsing) فيعني تفكيك هذه الروابط إلى أجزائها المكوّنة.
عندما أتحدث عن التحليل أو «أجزاء الرابط»، فأنا أقصد المكوّنات التالية:
انقر لعرض لقطة شاشة لمطابقة السلاسل الفرعية في RegEx101.
قبل الغوص عميقًا في التعبير النمطي، دعنا نستخدم أداة بصرية لنرى مدى قدرة نمطنا على التقاط العديد من المطابقات:

تعبير regex بحجم 120+ بايت
فيما يلي تعبير نمطي مختصر صُمم لاستخراج وتحليل الروابط في خطوة واحدة. يدعم بروتوكولات مختلفة، ونطاقات، ومسارات، وأقسام استعلام/جزء اختيارية.
لا تقلق — سنفصّله خطوة بخطوة!
const urlRegex = /([-.a-z0-9]+:\/{1,3})([^-\/\.[\](|)\s?][^`\/\s\]?]+)([-_a-z0-9!@$%^&*()=+;/~\.]*)[?]?([^#\s`?]*)[#]?([^#\s'"`\.,!]*)/gi;// Compatibility: ES5+// نفس النمط، مقسّم على أسطر لسهولة القراءة:([-.a-z0-9]+:\/{1,3})([^-\/\.[\](|)\s?][^`\/\s\]?]+)([-_a-z0-9!@$%^&*()=+;/~\.]*)[?]?([^#\s`?]*)[#]?([^#\s'"`\.,!]*)شارك أجرأ تعبير نمطي صادفته (أو كتبته) في التعليقات أدناه! 🚀
🧩 تفصيله خطوة بخطوة
دعونا نفكك التعبير النمطي إلى مكوّناته لفهم طريقة عمله:
1. البروتوكول (المجموعة 1): ([-.a-z0-9]+:/{1,3})
- الغرض: يطابق جزء البروتوكول من الرابط (مثل
http://،ftp://،custom-scheme://). الشرح:
[-.a-z0-9]+: يطابق حرفًا أو أكثر من الأحرف الصغيرة، الأرقام، الشرطات أو النقاط (شائع في مخططات البروتوكول).:/{1,3}: يطابق نقطتين متبوعتين بواحد إلى ثلاثة شرطات مائلة (:/،://، أو:///).
2. النطاق (المجموعة 2): ([^-/.[](|)s?][^`/s]?]+)
- الغرض: يلتقط جزء النطاق أو المضيف من الرابط.
الشرح:
[^-/.[](|)\s?]: يطابق أي حرف ما عدا الأحرف الخاصة المحددة والمسافات.[^`/\s]?]+: يطابق حرفًا أو أكثر ما عدا العلامات العكسية، الشرطات المائلة، المسافات، أو القوس المربع المغلق.
3. المسار (المجموعة 3): ([-_a-z0-9!@$%^&*()=+;/~\.]*)
- الغرض: يطابق مكوّن المسار في عنوان URL.
التفسير:
[-_a-z0-9!@$%^&()=+;/~.]: يطابق صفر أو أكثر من الأحرف الآمنة في URL والتي تُستخدم عادةً في المسارات.
4. الاستعلام (المجموعة 4): [?]?([^#\s`?]*)
- الغرض: يطابق اختياريًا سلسلة الاستعلام، بدءًا بأي حرف
?. التفسير:
[?]?: يطابق اختياريًا?. (الأقواس المربعة ليست ضرورية تمامًا، لكنها أكثر وضوحًا قليلًا من??المتقربة، وتوفر تماثلًا بصريًا مع المجموعة التالية[#]?.)([^#\s`?]*): يطابق صفر أو أكثر من الأحرف التي ليست علامة شباك، أو مسافة بيضاء، أو علامة اقتباس عكسية، أو علامة سؤال.
5. الجزء المقطّع (المجموعة 5): [#]?([^#\s’”`.,!]*)
- الغرض: يطابق اختياريًا معرف الجزء المقطّع بدءًا بـ
#. التفسير:
[#]?: يطابق اختياريًا#.([^#\s’”`.,!]*): يطابق صفر أو أكثر من الأحرف التي ليست علامات ترقيم محظورة أو مسافات بيضاء.
🛠️ مثال على التحليل
إليك كيفية تشغيل هذا التعبير النمطي الضخم باستخدام قليل من JavaScript:
const text = `Check this out: https://example.com/path?query=123#sectionAnd also (ftp://files.server.org/index).Plus a weird one: custom-scheme://host/param;weird^stuff`;
const urlRegex = /([-.a-z0-9]+:\/{1,3})([^-\/\.[\](|)\s?][^`\/\s\]?]+)([-_a-z0-9!@$%^&*()=+;/~\.]*)[?]?([^#\s`?]*)[#]?([^#\s'"`\.,!]*)/gi;
const matches = [ ...text.matchAll(urlRegex),].map((match) => match[0]);console.log("Extracted URLs:", matches);
const parts = [ ...text.matchAll(urlRegex),].map((match) => match.slice(1));console.log("Extracted Parts:", parts);[ "https://example.com/path?query=123#section", "ftp://files.server.org/index", "custom-scheme://host/param;weird^stuff"][ [ "https://", // Protocol "example.com", // Domain "/path", // Path "query=123", // Query "section" // Fragment ], [ "ftp://", // Protocol "files.server.org", // Domain "/index", // Path "", // Query "" // Fragment ], [ "custom-scheme://", // Protocol "host", // Domain "/param;weird^stuff", // Path "", // Query "" // Fragment ]]☑️ الخطوات التالية
اعتمادًا على حالتك، قد تحتاج إلى صقل هذا التعبير النمطي أو إضافة المزيد من خطوات التحقق والمعالجة اللاحقة.
مشاريع مختلفة، احتياجات مختلفة
المشاريع لها متطلبات ومخاوف أمنية متفاوتة:
- استخلاص الويب: التحقق من صحة عناوين URL لضمان إمكانية الوصول إليها وثقتها.
- معالجة البيانات: استخراج عناوين URL من المحتوى الذي يولده المستخدم مع الحفاظ على الأمان.
- تحليل البيانات: تصفية الروابط المكررة أو غير ذات الصلة لأغراض البحث أو التسويق.
- التطبيقات الموجهة للمستخدم: تحويل عناوين URL تلقائيًا إلى روابط في تطبيقات الدردشة أو المنتديات.
ما بعد المعالجة والتحقق
بعد جمع عناوين URL المحتملة، طبّق فحوصات إضافية:
- استعلام DNS: التأكد من أن النطاقات تُحل.
- فحوصات الأمان: استخدام خدمات للتحقق من المواقع الخبيثة أو الاحتيالية.
- قواعد مخصصة: تطبيق مرشحات خاصة بالمشروع (مثل السماح بـ TLDs معينة، الحد الأقصى لطول URL).
📝 ملخص
استخلاص البيانات النصية شبه المهيكلة قد يكون أكثر جوانب إتقان الـ regex إرضاءً.
إليك ملخص للنقاط الرئيسية:
- استخدم أداة بصرية لكتابة واختبار وفهم أنماط Regex الخاصة بك.
- قسّم التحدي إلى أجزاء وحل كل جزء على حدة. بمعنى ما، توفر مجموعات الالتقاط علامات “دليلية” رمزية للـ regex.
- استخدم تعبيرات مطابقة “فضفاضة”، وتجنب الالتزام الصارم بالمواصفات عند استهلاك البيانات.
- تطبيق خطوات التحقق بعد الاستخلاص الأولي أمر أساسي—دائمًا ضع في اعتبارك أمان مشروعك واحتياجاته الخاصة.
باتباع هذه الخطوات، يمكنك استخراج أي بيانات نصية شبه مُهيكلة بفعالية، مما يضع الأساس للمعالجة اللاحقة والتحقق.
📚 مزيد من التعلم
- تذكر أن تُجرب عرضًا حيًا على RegEx101.com!
- سؤال StackOverflow الأصلي، ورابط إجابتي هنا.
- وثائق MDN حول التعبيرات النمطية
- تقنيات Regex المتقدمة: استكشف lookaheads وlookbehinds وأنماطًا متقدمة أخرى لمطابقة أكثر دقة.
- RFC 3986 - بنية URI العامة