توفر التعبيرات العادية (Regular Expression) طريقة فعالة ومريحة لمطابقة أنماط السلسلة. توفر جميع اللغات عالية المستوى تقريبًا دعمًا للتعبيرات العادية أو توفر مكتبات أكواد جاهزة للاتصال. تتناول هذه المقالة مهام المعالجة الشائعة في بيئة ASP كمثال لتقديم المهارات التطبيقية للتعبيرات العادية.
1. التحقق من تنسيق كلمات المرور وعناوين البريد الإلكتروني
يوضح مثالنا الأول وظيفة أساسية للتعبيرات العادية: الوصف التجريدي للسلاسل المعقدة بشكل عشوائي. ما يعنيه ذلك هو أن التعبيرات العادية تمنح المبرمجين طريقة رسمية لوصف السلسلة يمكنها وصف أي نمط سلسلة يواجهه التطبيق بكمية صغيرة فقط من التعليمات البرمجية. على سبيل المثال، بالنسبة للأشخاص الذين لا يعملون في العمل الفني، يمكن وصف متطلبات تنسيق كلمة المرور على النحو التالي: يجب أن يكون الحرف الأول من كلمة المرور حرفًا، ويجب أن لا تقل كلمة المرور عن 4 أحرف ولا تزيد عن 15 حرفًا، لا يمكن أن تحتوي كلمة المرور إلا على أحرف وأرقام وأحرف غير الشرطة السفلية.
كمبرمجين، يجب علينا تحويل وصف اللغة الطبيعية أعلاه لتنسيق كلمة المرور إلى نماذج أخرى حتى تتمكن صفحة ASP من فهمه وتطبيقه لمنع الإدخال غير القانوني لكلمة المرور. التعبير العادي الذي يصف تنسيق كلمة المرور هذا هو: ^[a-zA-Z]w{3,14}$.
في تطبيقات ASP يمكننا كتابة عملية التحققمن
كلمة المرور كوظيفة قابلة لإعادة الاستخدام، كما هو موضح أدناه:
إعادة خافتة
تعيين إعادة = RegExp الجديد
re.IgnoreCase = خطأ
re.global = false
re.Pattern = "^[a-zA-Z]w{3,14}$"
TestPassword = re.Test(strPassword)
وظيفة النهاية
نقارن أدناه التعبير العادي للتحقق من تنسيق كلمة المرور مع وصف اللغة الطبيعية:
يجب أن يكون الحرف الأول لكلمة المرور حرفًا: وصف التعبير العادي هو "^[a-zA-Z]"، حيث " ^" تشير إلى بداية السلسلة، وتطلب الواصلة من RegExp أن يطابق كافة الأحرف الموجودة في النطاق المحدد.
يجب أن تتكون كلمة المرور من 4 أحرف على الأقل ولا تزيد عن 15 حرفًا: وصف التعبير العادي هو "{3,14}".
لا يمكن أن تحتوي كلمة المرور على أحرف غير الأحرف والأرقام والشرطات السفلية: وصف التعبير العادي هو "w".
بعض الملاحظات: {3، 14} يعني أن النمط السابق يطابق 3 على الأقل ولكن لا يزيد عن 14 حرفًا (بالإضافة إلى الحرف الأول، يصبح من 4 إلى 15 حرفًا). لاحظ أن بناء الجملة داخل الأقواس المتعرجة صارم للغاية ولا يسمح بوجود مسافات على جانبي الفاصلة. إذا تمت إضافة مسافات، فسوف يؤثر ذلك على معنى التعبير العادي ويسبب أخطاء أثناء التحقق من تنسيق كلمة المرور. بالإضافة إلى ذلك، لا تتم إضافة الحرف "$" في نهاية التعبير العادي أعلاه. يؤدي الحرف $ إلى مطابقة التعبير العادي للسلسلة حتى النهاية، مما يضمن كلمة مرور صالحة دون أي أحرف إضافية تتبعها.
كما هو الحال مع التحقق من تنسيق كلمة المرور، يعد التحقق من شرعية عناوين البريد الإلكتروني مشكلة شائعة جدًا أيضًا. يمكن تنفيذ استخدام التعبيرات العادية لإجراء التحقق البسيط من عنوان البريد الإلكتروني على النحو التالي:
<%.
إعادة خافتة
تعيين re = new RegExp
re.pattern = "^w+@[a-zA-Z_]+?.[a-zA-Z]{2,3}$"
Response.Write re.Test(" [email protected] ")
%>
2. استخراج أجزاء معينة من صفحة HTML
المشكلة الرئيسية التي نواجهها عند استخراج المحتوى من صفحة HTML هي أننا يجب أن نجد طريقة لتحديد جزء المحتوى الذي نريده بدقة. على سبيل المثال، ما يلي هو مقتطف تعليمات برمجية بتنسيق HTML يعرض عناوين الأخبار:
<table border="0" width="11%" class="Somestory">
<tr>
<عرض td = "100%">
<p align="center">محتوى آخر...</td>
</tr>
</الجدول>
< حدود الجدول = "0" العرض = "11%" فئة = "العنوان">
<tr>
<عرض td = "100%">
<p align="center">الحرب في العراق! </تد>
</tr>
</الجدول>
< حدود الجدول = "0" العرض = "11%" فئة = "قصة ما">
<tr>
<عرض td = "100%">
<p align="center">محتوى آخر...</td>
</tr>
</table>
من خلال مراقبة الكود أعلاه، من السهل أن نرى أن عنوان الأخبار يتم عرضه بواسطة الجدول في المنتصف، ويتم تعيين سمة فئته على Headline. إذا كانت صفحة HTML معقدة للغاية، فيمكنك استخدام ميزة إضافية مقدمة من Microsoft IE بدءًا من الإصدار 5.0 لعرض كود HTML الخاص بالجزء المحدد من الصفحة فقط، برجاء زيارة http://www.microsoft.com/Windows/ie /WebAccess/default.ASP اعرف المزيد. في هذا المثال، نفترض أن هذا هو الجدول الوحيد الذي تم تعيين سمة فئته على العنوان الرئيسي. نحن الآن بحاجة إلى إنشاء تعبير عادي، والعثور على جدول العنوان هذا من خلال التعبير العادي، وإدراج هذا الجدول في صفحتنا الخاصة. الأول هو كتابة كود يدعم التعبيرات العادية:
<%
خافت إعادة، strHTML
Set re = new RegExp ' إنشاء كائن تعبير عادي
re.IgnoreCase = true
re.Global = false 'إنهاء البحث بعد المطابقة الأولى
%>
الآن فكر في المنطقة التي نريد استخراجها: هنا، ما نريد استخراجه هو بنية <table> بأكملها، بما في ذلك علامة الإغلاق ونص عنوان الأخبار. لذلك، يجب أن يكون حرف بداية البحث هو علامة البداية <table>: re.Pattern = "<table.*(?=Headline)". يتطابق هذا التعبير العادي مع علامة البداية للجدول ويمكنه إرجاع كل شيء بين علامة البداية و"العنوان" (باستثناء الأسطر الجديدة). فيما يلي كيفية إرجاع رمز HTML المطابق:
"ضع كافة رموز HTML المطابقة في مجموعة التطابقات."
Set Matches = re.Execute(strHTML)
'عرض كافة رموز HTML المتطابقة
لكل عنصر في المباريات
الاستجابة.اكتب العنصر.القيمة
التالي
"إظهار واحدة من."
Response.write Matches.Item(0).Value
يقوم بتشغيل هذه التعليمات البرمجية لمعالجة جزء HTML الموضح سابقًا، ويعيد التعبير العادي محتوى المطابقة كما يلي: <table border="0" width="11%" class=". التعبير العادي "(؟=العنوان الرئيسي)" في التعبير لا يحصل على الأحرف، لذلك لا يمكن رؤية قيمة سمة فئة الجدول، وهو أيضًا بسيط جدًا: re.Pattern = "<table.*(?=Headline) (.|n)*?</table>". من بينها: "*" بعد "(.|n)" يطابق 0 مع أي أحرف أخرى؛ "يقلل نطاق المطابقة "*"، أي يطابق أقل عدد ممكن من الأحرف قبل العثور على الجزء التالي من التعبير </table> هو علامة نهاية الجدول.
المحدد "؟" مهم جدًا، فهو يمنع التعبير من إرجاع التعليمات البرمجية للجداول الأخرى على سبيل المثال، بالنسبة لمقتطف تعليمات HTML البرمجية المذكور أعلاه، إذا قمت بحذف هذا "؟"، فسيكون المحتوى الذي تم إرجاعه هو:
<table border="0" width="11%" class=". العنوان">
<tr>
<عرض td = "100%">
<p align="center">الحرب في العراق! </تد>
</tr>
</الجدول>
< حدود الجدول = "0" العرض = "11%" فئة = "قصة ما">
<tr>
<عرض td = "100%">
<p align="center">محتوى آخر...</td>
</tr>
</الجدول>
لا يحتوي المحتوى الذي تم إرجاعه على علامة <table> الخاصة بالجدول Headline فحسب، بل يحتوي أيضًا على جدول Someotherstory.
يفترض هذا المثال بعض المباني المثالية إلى حد ما. في التطبيقات الفعلية، غالبًا ما يكون الموقف أكثر تعقيدًا، خاصة عندما لا يكون لديك أي تأثير على كتابة كود HTML المصدر المستخدم، وتكون كتابة كود ASP أمرًا صعبًا بشكل خاص. الطريقة الأكثر فعالية هي قضاء المزيد من الوقت في تحليل HTML بالقرب من المحتوى المراد استخراجه، واختباره بشكل متكرر للتأكد من أن المحتوى المستخرج هو بالضبط ما تحتاجه. بالإضافة إلى ذلك، يجب عليك الانتباه إلى الموقف الذي لا يمكن أن يتطابق فيه التعبير العادي مع أي محتوى لصفحة HTML المصدر والتعامل معه. يمكن أن يتغير المحتوى بسرعة كبيرة، لذلك لا ينتهي الأمر بأخطاء سخيفة على صفحتك لمجرد قيام شخص آخر بتغيير تنسيق المحتوى.
3. تحليل ملفات البيانات النصية
هناك العديد من تنسيقات وأنواع ملفات البيانات، وغالبًا ما تصبح النصوص المنظمة وحتى النصوص غير المنظمة مصادر بيانات لتطبيقات ASP. أحد الأمثلة التي سننظر إليها أدناه هو ملف نصي منظم يستخدم المؤهلات. تشير المؤهلات (مثل علامات الاقتباس) إلى أن أجزاء السلسلة غير قابلة للفصل، حتى لو كانت السلسلة تحتوي على محددات تفصل السجل إلى حقول.
فيما يلي ملف نصي منظم بسيط:
الاسم
الأخير، الاسم الأول، رقم الهاتف، الوصف Sun، Wukong، 312 555 5656، ASP جيد جدًا، Pig، Bajie، 847 555 5656، أنا منتج أفلام
بسيط، السطر الأول هو العنوان والسطرين التاليين هما السجلات مفصولة بفواصل. يعد تحليل هذا الملف أمرًا بسيطًا جدًا أيضًا، ما عليك سوى تقسيم الملف إلى أسطر (وفقًا لرموز السطر الجديد)، ثم تقسيم كل سجل وفقًا للحقول. ومع ذلك، إذا أضفنا فواصل إلى محتوى حقل معين:
الاسم الأخير، الاسم الأول، رقم الهاتف، الوصف Sun، Wukong، 312 555 5656، فأنا أحب ASP وVB وSQL
Pig، Bajie، 847 555 5656، أنا منتج أفلام.
ستكون هناك مشكلة عند تحليل السجل الأول، لأنه في نظر المحلل اللغوي الذي يتعرف فقط على محددات الفاصلة، يحتوي الحقل الأخير على محتويات حقلين. لتجنب هذا النوع من المشاكل، يجب أن تكون الحقول التي تحتوي على المحددات محاطة بالمؤهلات. علامات الاقتباس الفردية هي مؤهل شائع الاستخدام. بعد إضافة مؤهل الاقتباس الفردي إلى الملف النصي أعلاه، يكون محتواه كما يلي:
الاسم الأخير، الاسم الأول، رقم الهاتف، الوصف Sun، Wukong، 312 555 5656، 'I like ASP وVB وSQL'
Zhu, Bajie, 847 555 5656، 'أنا منتج أفلام'
الآن يمكننا تحديد أي فاصلة هي الفاصلة وأي فاصلة هي محتوى الحقل، أي أننا نحتاج فقط إلى اعتبار الفواصل التي تظهر داخل علامات الاقتباس هي المحتوى من الميدان. والشيء التالي الذي يتعين علينا القيام به هو تنفيذ محلل التعبير العادي الذي يحدد متى يتم تقسيم الحقول بناءً على الفواصل ومتى يتم التعامل مع الفواصل كمحتوى حقل.
المشكلة هنا مختلفة قليلاً عما تواجهه معظم التعبيرات العادية. عادةً ما ننظر إلى جزء صغير من النص لمعرفة ما إذا كان يطابق التعبير العادي. ولكن هنا، لا يمكننا معرفة ما هو موجود داخل علامات الاقتباس بشكل موثوق إلا بعد النظر في سطر النص بأكمله.
إليك مثال يوضح المشكلة. قم باستخراج نصف سطر من المحتوى بشكل عشوائي من ملف نصي واحصل على: 1، beach، black، 21، '، dog، cat، duck،'، . في هذا المثال، نظرًا لوجود بيانات أخرى على يسار الرقم "1"، فمن الصعب جدًا تحليل محتواها. لا نعرف عدد علامات الاقتباس المفردة التي تسبق جزء البيانات هذا، لذا لا يمكننا تحديد الأحرف الموجودة ضمن علامات الاقتباس (لا يمكن تقسيم النص الموجود داخل علامات الاقتباس أثناء التحليل). إذا كان جزء البيانات مسبوقًا بعلامات اقتباس مفردة ذات رقم زوجي (أو لا)، فإن "'، dog، cat، duck، '" عبارة عن سلسلة مقتبسة وغير قابلة للتجزئة. إذا كان عدد علامات الاقتباس السابقة عددًا فرديًا، فإن "1، beach، black، 21، '" هي نهاية السلسلة وهي غير قابلة للتجزئة.
لذلك، يجب أن يقوم التعبير العادي بتحليل سطر النص بالكامل، مع الأخذ في الاعتبار عدد علامات الاقتباس التي تظهر لتحديد ما إذا كان الحرف داخل زوج علامات الاقتباس أو خارجه، أي:,(?=([^']*'[ ^']*') *(؟![^']*')). يبحث هذا التعبير العادي أولاً عن علامة اقتباس، ثم يستمر في البحث ويتأكد من أن عدد علامات الاقتباس المفردة بعد الفاصلة إما أن يكون رقمًا زوجيًا أو صفرًا. يعتمد هذا التعبير العادي على الحكم التالي: إذا كان عدد علامات الاقتباس المفردة بعد الفاصلة زوجيًا، فإن الفاصلة تكون خارج السلسلة. يقدم الجدول التالي تعليمات أكثر تفصيلاً:
، البحث عن فاصلة
(؟= يواصل البحث لمطابقة هذا النمط:
(ابدأ نمطًا جديدًا
[^']*' [أحرف بدون علامات اقتباس] 0 أو أكثر، متبوعة بعلامة اقتباس
[^']*'[^']*) [أحرف بدون علامات اقتباس] 0 أو أكثر، متبوعة بعلامة اقتباس. بالاشتراك مع المحتوى السابق فإنه يطابق أزواج الاقتباس
)* ينهي النمط ويطابق النمط بأكمله (أزواج علامات الاقتباس) 0 مرة أو أكثر
(؟! ابحث للأمام، استبعد هذا النمط
[^']*' [أحرف بدون علامات اقتباس] 0 أو أكثر، متبوعة بعلامة اقتباس
) أسفل وضع النهاية
توجد وظيفة VBScript، التي تقبل معلمة سلسلة، وتقسم السلسلة وفقًا لفاصل الفاصلة ومؤهل الاقتباس المفرد في السلسلة، وترجع مصفوفة النتائج:
Function SplitAdv(strInput)
كائن خافت
Set objRE = new RegExp
'تعيين كائن RegExp
objRE.IgnoreCase = true
objRE.Global = صحيح
objRE.Pattern = ",(?=([^']*'[^']*')*(؟![^']*'))"
' تستخدم طريقة الاستبدال chr(8) لاستبدال ما نريده لاستخدام الفاصلة، chr(8) هوb
'، قد يظهر b نادرًا جدًا في السلسلة.
' ثم نقوم بتقسيم السلسلة وفقًا لـ b وحفظها في المصفوفة
SplitAdv = سبليت(objRE.Replace(strInput, "b"), "b")
وظيفة النهاية
باختصار، فإن استخدام التعبيرات العادية لتحليل ملفات البيانات النصية له مزايا الكفاءة العالية وتقصير وقت التطوير، ويمكن أن يوفر الكثير من الوقت في تحليل الملفات واستخراج البيانات المفيدة بناءً على الظروف المعقدة. في بيئة سريعة التطور حيث لا يزال هناك الكثير من البيانات التقليدية المتاحة، فإن معرفة كيفية إنشاء إجراءات فعالة لتحليل البيانات ستكون مهارة قيمة.
4. استبدال السلسلة
في المثال الأخير، سنلقي نظرة على وظيفة الاستبدال للتعبيرات العادية لـ VBScript. غالبًا ما يتم استخدام ASP لتنسيق النص الذي تم الحصول عليه من مصادر البيانات المختلفة ديناميكيًا. باستخدام قوة تعبيرات VBScript العادية، يمكن لـ ASP تغيير النص المعقد المطابق ديناميكيًا. يعد تمييز بعض الكلمات عن طريق إضافة علامات HTML أحد التطبيقات الشائعة، مثل تمييز الكلمات الرئيسية للبحث في نتائج البحث.
لتوضيح كيفية القيام بذلك، دعونا نلقي نظرة على مثال يسلط الضوء على كل ".NET" في سلسلة. يمكن الحصول على هذه السلسلة من أي مكان، مثل قاعدة بيانات أو موقع ويب آخر.
<%
قم بتعيين regEx = New RegExp
regEx.Global = صحيح
regEx.IgnoreCase = صحيح
"نمط التعبير العادي،
"ابحث عن أي كلمة أو عنوان URL ينتهي بـ ".NET".
regEx.Pattern = "(b[a-zA-Z._]+?.NETb)"
' السلسلة المستخدمة لاختبار وظيفة الاستبدال
strText = "قامت Microsoft بإنشاء موقع ويب جديد www.ASP.NET ."
'استدعاء أسلوب الاستبدال للتعبير العادي
'$1 يعني إدراج النص المطابق في الموضع الحالي
الاستجابة.اكتب regEx.Replace(strText, _
"<b style='color: #000099; حجم الخط: 18pt'>$1</b>")
%>
هناك عدة نقاط مهمة يجب الإشارة إليها في هذا المثال. يتم وضع التعبير العادي بأكمله بين قوسين، وتتمثل وظيفته في اعتراض كل المحتوى المطابق لاستخدامه لاحقًا، والذي تتم الإشارة إليه بـ $1 في النص البديل. يمكن استخدام ما يصل إلى 9 اعتراضات مماثلة لكل استبدال، يشار إليها بـ $1 إلى $9 على التوالي. تختلف طريقة الاستبدال للتعبيرات العادية عن وظيفة الاستبدال في VBScript نفسها، فهي تتطلب معلمتين فقط: النص المطلوب البحث فيه والنص المراد استبداله.
في هذا المثال، لتمييز سلاسل ".NET" التي تم البحث عنها، قمنا بإحاطتها بعلامات عريضة وسمات نمط أخرى. باستخدام تقنية البحث والاستبدال هذه، يمكننا بسهولة إضافة وظيفة تمييز الكلمات الرئيسية للبحث إلى برنامج البحث في موقع الويب، أو إضافة روابط تلقائيًا إلى صفحات أخرى للكلمات الرئيسية التي تظهر على الصفحة.
خاتمة
آمل أن تكون تقنيات التعبير العادي المتعددة المقدمة في هذه المقالة قد ألهمتك متى وكيف يتم تطبيق التعبيرات العادية. على الرغم من أن الأمثلة الواردة في هذه المقالة مكتوبة بلغة VBScript، إلا أن التعبيرات العادية مفيدة أيضًا في ASP.NET وهي إحدى الآليات الرئيسية للتحقق من صحة نموذج التحكم من جانب الخادم، ويتم تصديرها إلى مساحة الاسم .Text.RegularExpressions بالكامل من خلال النظام. مساحة اسم .Text.RegularExpressions NET.