توقعًا لبدء سلسلة جديدة في الدورة التدريبية "Backend-developer in PHP" ، وكذلك الدورة التدريبية ذات الصلة "Framework Laravel" ، نريد مشاركة المقالة التي أعدها مؤلفنا المستقل.
تحذير! هذه المقالة ليست ذات صلة ببرنامج الدورة التدريبية وستكون مفيدة للمبتدئين فقط . لمزيد من المعرفة المتعمقة ، ندعوك إلى زيارة مكثفة مجانية لمدة يومين عبر الإنترنت حول هذا الموضوع: "إنشاء روبوت Telegram لطلب القهوة في مؤسسة والدفع عبر الإنترنت" . في اليوم الثاني من مكثفة سيعقد هنا .

مرحبا بالجميع! كل ذلك مع السنة القادمة
[20]{2,}0
. اليوم أريد أن أتناول موضوعًا يكون أحيانًا موضوعًا للنكات من "نعم ، لماذا تحتاج إلى تعلم كل هذا إذا كان لديك بالفعل حلول جاهزة" إلى "هل يمكنك أيضًا تعلم كل لغة بيرل؟". ومع ذلك ، مع مرور الوقت ، يبدأ العديد من المبرمجين في إتقان التعبيرات العادية ، ولا يوجد في Habré مقال جديد واحد (
على الرغم من أن التعبيرات العادية لم تتغير كثيرًا مؤخرًا ) حول هذا الموضوع. حان الوقت لكتابة واحدة أخرى!
التعبيرات المنتظمة بمعزل عن تنفيذها المحدد
تعد التعبيرات المعتادة (المشار إليها بالإنجليزية باسم
RegEx أو
regex ) أداة تُستخدم لمختلف الخيارات لدراسة النص ومعالجته: البحث ، والتحقق ، والبحث ، واستبدال عنصر يتكون من أحرف أو أرقام (أو أي أحرف أخرى في بما في ذلك الأحرف الخاصة وأحرف الترقيم). في البداية ، جاءت تعبيرات منتظمة إلى عالم البرمجة من بيئة البحث العلمي ، والتي أجريت في الخمسينيات في مجال الرياضيات.
بعد مرور عقود ، تم نقل المبادئ والأفكار إلى بيئة نظام التشغيل UNIX (على وجه الخصوص ، تم تضمينها في الأداة المساعدة
grep
) وتم تنفيذها بلغة البرمجة في Perl ، والتي كانت تستخدم على نطاق واسع في فجر الإنترنت على الواجهة الخلفية (وحتى يومنا هذا ، ولكن أقل بالفعل) لمثل هذه المهمة مثل التحقق من صحة النموذج.

إذا كانت تبدو بسيطة ، فلماذا مخيف جداً للوهلة الأولى؟
في الواقع ، يمكن أن يكون أي تعبير "عادي" ويمكن استخدامه للتحقق أو البحث عن أي أحرف. على سبيل المثال ، يمكن أيضًا استخدام الكلمات
Pavel أو
example@mail.ru كأدوات عادية ، فقط ، بالطبع ، في مفتاح ضيق نوعًا ما. لاختبار أداء التعبيرات العادية في بيئة PHP دون بدء تشغيل الخادم أو الاستضافة ، يمكنك استخدام
الخدمة عبر الإنترنت التالية (لا تعمل فقط مع معالجة الأحرف الروسية عليها). بالنسبة للمبتدئين ، نستخدم
Pavel كتعبير منتظم.
لنفترض أن لدينا النص التالي:
بافل يعرف الكثير.
بافل باستخدام nginx وانه ليس متسكع.
الآن ، وجدت التعبيرات العادية كلاً من تكرارات كلمة Pavel. إنه شيء رائع ، لكنه لا يبدو مفيدًا للغاية (إلا إذا كنت تحاول لسبب ما تحليل ما يشبه كلمة
سيدي في الحرب والسلام من خلال Vim و Python ، ولكن بعد ذلك ليس لدي أسئلة لك).
تقلب التعبير
إذا كان تعبيرك العادي متغيرًا (على سبيل المثال ، فأنت تعرف جزءًا منه فقط وتحتاج إلى العثور على عدد مرات ظهور السنين ، بدءًا من عام 2000 وتنتهي عام 2099) ، ثم يمكننا استخدام التعبير العادي التالي:
20 ..النص: يكتب الكتاب الشباب الكثير من الأشياء. على سبيل المثال ، يختلف الكاتب الذي وُلد عام 2002 اختلافًا كبيرًا عن عامي 2008 و 2012.هنا ، بمساعدة التعبيرات العادية ، يمكننا أن نجد كل السنين ، لكن هذا لا معنى له حتى الآن. على الأرجح ، لسنا بحاجة إلى سنوات بعد عام 2012 (على الرغم من أن الكتاب الشباب الذين تقل أعمارهم عن 8 سنوات قد يتعرضون للإهانة ، ولكن ليس ذلك الآن). الأمر يستحق دراسة مجموعات الأحرف ، ولكن المزيد عن ذلك لاحقًا ، لأننا الآن سنتحدث عن جزء مهم آخر من التعبيرات العادية: الهروب من الحروف الأولية.
تخيل أننا بحاجة إلى العثور على عدد مرات تواجد الملفات ذات الامتداد
.doc
(لنفترض أننا نصدر فقط بعض الملفات التي تم تحميلها إلى قاعدة البيانات الخاصة بنا). ولكن هل تعني النقطة ببساطة أي شخصية؟ ماذا تفعل؟
هنا ، الهروب من الحروف الأولية بخط مائل عكسي يأتي لمساعدتنا. الآن سيكون التعبير
\.doc
ناجحًا بدرجة كافية للبحث عن أي نص يذكر بالملحق
.doc
:
التعبير العادي:
\.doc
النص: kursach
.doc ،
nepodozritelneyfail.exe
، العمل
.doc ،
shaprgalka.rtf doc
كما ترون ، يمكننا العثور بنجاح على عدد الملفات ذات الملحق
.doc
في القائمة. ومع ذلك ، لا يمكننا سحب أسماء الملفات الكاملة باستخدام هذا التعبير العادي ، على سبيل المثال ، في صفيف. حان الوقت لإلقاء نظرة على مجموعات الأحرف.
تطابق مجموعة كاملة من الشخصيات
في التعبيرات العادية ، يتم توفير المطابقة مع مجموعة باستخدام الحروف الأولية - الأقواس المربعة
[ ]
. يمكن تحديد أي حرفين ASII كبداية ونهاية نطاق. للتنفيذ البسيط ، افترض أننا نريد العثور على جميع الملفات ذات الأرقام من 0 إلى 9 مع الامتداد
.jpg
.
تعبير عادي:
[0-9]\.jpg
النص:
1.jpg ،
2.jpg ،
3.jpg ، photo.jpg ، anime.jpg ،
8.jpg ، jkl.jpg
تجدر الإشارة إلى أن اسم الملف لأكثر من رقم واحد لن تتم تغطيته بواسطة تعبيرنا العادي. سيكون الاختيار من متعدد أقل قليلاً ، ولكن تخيل الآن أننا نحتاج فجأة لتحقيق النتيجة المعاكسة. أضف metacharacter
^
(والذي ، على العكس ، له دالتان في تعبيرات عادية). لاستخدامها كاستثناء ، تحتاج إلى إضافتها تمامًا إلى مجموعتنا:
تعبير عادي:
[^0-9]\.jpg
النص: 1.jpg ، 2.jpg ، 3.jpg ، فوت
o.jpg ، anim
e.jpg ، 8.jpg ، jk
l.jpgلكن بدون اختيارات متعددة ، هذه بالطبع تعبيرات رديئة.
طاولات مفيدة
هنا جدول من الحروف الأولية:
الجدول metacharacters الفضاء الأبيض
الاختيار من متعدد: جعل التحقق من صحة بسيطة
مسلحًا بالمعرفة المكتسبة ، سنحاول إنشاء تعبير منتظم يجد ، على سبيل المثال ، كلمات أقصر من 3 أحرف (مهمة قياسية لمكافحة البريد العشوائي). إذا حاولنا استخدام التعبير المنتظم التالي -
\w{1,3}
(حيث يشير الحرف الميكانيكي
\w
إلى أي حرف ، وتشير الأقواس المتعرجة إلى عدد الأحرف من العدد إلى العدد ، فسنقوم بإبراز جميع الأحرف في صف واحد - ستحتاج إلى تعيين بطريقة أو بأخرى بداية ونهاية الكلمات في النص ، لهذا نحتاج إلى الحرف المائل
\b
.
تعبير عادي:
\b\w{1,3}\b:
النص: كلمة طيبة
ليسبيضةليس سيئا! الآن الكلمات الأقصر من ثلاثة أحرف لن تكون قادرة على الوصول إلى قاعدة البيانات الخاصة بنا. دعونا ننظر في التحقق من صحة العنوان البريدي:
تعبير عادي:
\w+@\w+\.\w+
المتطلبات: في البريد الإلكتروني في البداية ، يجب أن يكون هناك أي حرف (الأرقام أو الحروف ، لأن البريد الإلكتروني ، الذي يتكون فقط من الأرقام في البداية ، أمر شائع جدًا). ثم يأتي الرمز
@
، ثم أكبر عدد تريده من الأحرف ، متبوعًا بنقطة نجت (أي مجرد نقطة) ونطاق المستوى الأول.
النظر في تكرار حرف بمزيد من التفاصيل.
الآن دعونا نلقي نظرة فاحصة على كيفية تكرار الحروف في التعبيرات العادية. على سبيل المثال ، تريد العثور على أي مجموعة من الأرقام من 2-6 في النص:
تعبير عادي:
[2-6]+
النص: هنا يأتي 89 مختلفة
234 أرقام
24 .
اسمحوا لي أن أقدم لكم جدولا لجميع الكميات metacharacter:
لا يوجد شيء معقد حول تطبيق الكميات. باستثناء تحذير واحد: الكمي الجشع والكسل. هنا هو الجدول:
تختلف الكميات الكاسفة عن الجشع في أنها تستحوذ على الحد الأدنى وليس الحد الأقصى لعدد الأحرف. تخيل أن لدينا مهمة للعثور على جميع علامات h1-h6 للرأس ومحتواها ، ويجب ألا تتأثر بقية النص (لقد قمت عمداً بإدخال علامة h7 غير الموجودة حتى لا تتعذب مع الفرار من علامات Habra):
تعبير عادي: <h [1-7]>. *؟ <\ / H [1-7]>
Text:
<
h7
>
hello </
h7
>
lorem ipsum avada kedavra
<
h7
> buy <
/h7
>
كل شيء يعمل بنجاح ، ولكن فقط بفضل الكمي كسول. في حالة استخدام الكمي الجشع ، فإن كل النص الموجود بين العلامات سيكون بارزًا (أعتقد أن هذا لا يحتاج إلى توضيح).
حدود سلسلة الأحرف
حدود سلاسل الأحرف التي استخدمناها بالفعل أعلاه. هنا جدول أكثر تفصيلا:
العمل مع subexpressions
تتم التعبيرات الفرعية في التعبيرات العادية باستخدام metacharacter المجموعة
()
.
فيما يلي مثال على تعبير عادي يمكنه العثور على أشكال مختلفة من عناوين IP عالميًا.
تعبير عادي: (((25 [0-5]) | (2 [0-4] \ d) | (1 \ d {2}) | (\ d {1،2})) \.) {3} (((25 [0-5] | (2 [0-4] \ d) | (1 \ d {2}) | (\ d {1،2}))))
النص:
255.255.255.255 هو مجرد عنوان
191.198.174.192 ويكيبيديا
87.240.190.67 vk
31.13.72.36 الفيسبوك
ويستخدم المشغل المنطقي
|
(أو) الذي يسمح لنا بتكوين تعبير منتظم يطابق القاعدة التي يتم بها تجميع عناوين IP. يجب أن يحتوي عنوان IP على 1 إلى 3 أرقام ، حيث يمكن أن يبدأ عدد من ثلاثة أرقام برقم واحد ، أو برقم 2 (أو بعد ذلك يجب أن يكون الرقم الثاني بين 0 و 4) ، أو يبدأ برقم 25 ، ثم 3 أرقام تبين أن بين 0 و 5. أيضا ، يجب أن يكون هناك نقطة بين كل مجموعة من الأرقام. باستخدام الجداول أعلاه ، حاول فك تشفير التعبير العادي في الأعلى. التعبيرات المنتظمة في البداية تخيفك بطولها ، لكن المدة الطويلة لا تعني التعقيد.
انظر إلى الأمام
لعرض تعبير عن أي مجموعة من أحرف معينة ، تتم الإشارة إلى نمط يتم من خلاله اكتشاف التطابق ، ولكن لا يتم إرجاعه. في الأساس ، يحدد التطلع إلى الأمام تعبيرًا فرعيًا ، وبالتالي يتم تشكيله وفقًا لذلك. يتكون نمط بناء الجملة للتطلع إلى الأمام من تعبير فرعي يسبقه؟ = ، ومن ثم يتبع النص المراد مطابقته.
هذه مهمة محددة: هناك كلمة مرور يجب أن تتكون من 7 أحرف على الأقل ويجب أن تتضمن بالضرورة حرفًا واحدًا ورقمًا واحدًا على الأقل. سيكون كل شيء هنا أكثر تعقيدًا إلى حد ما ، لأن المستخدم يجب أن يكون قادرًا على وضع الحرف الكبير في بداية الجملة وفي منتصفها (ويجب تكرار نفس الشيء مع الحرف).
لذلك ، نحن بحاجة إلى أن نتطلع إلى التعبير. بالإضافة إلى ذلك ، نحتاج إلى تقسيم العلامات إلى مجموعات. وأريد أن أحدد أحجامها من 8 إلى 22 حرفًا:
تعبير عادي:
/^(?=.*[az])(?=.*[AZ])(?=.*\d)[a-zA-Z\d]{8,}$/
النص:
Qwerty123Im789098weakpassword
ميزات العمل من التعبيرات العادية في PHP
لمعرفة كيفية عمل التعبيرات العادية في PHP ، قم بدراسة الوظائف الموجودة في وثائق PCRE الرسمية (تعبيرات Perl المتوافقة العادية) ، والتي تتوفر على الموقع الرسمي. يجب إرفاق التعبير في المحددات ، على سبيل المثال ، في خطوط مائلة للأمام.
يمكن أن تكون الأحرف العشوائية محددًا ، باستثناء الأحرف الأبجدية الرقمية ، والخط المائل العكسي '\' والبايت صفر. إذا ظهر الحرف المحدد في النموذج ، فيجب تجاوزه \. كما فواصل ، مجموعات تأتي من بيرل: () ، {} ، [].
ما هي الوظائف المستخدمة في php؟ توفر حزمة PCRE الميزات التالية لدعم التعبيرات العادية:
- preg_grep () - يقوم بإجراء بحث وإرجاع مجموعة من التطابقات.
- preg_match () - يبحث عن المطابقة الأولى باستخدام التعبيرات العادية
- preg_match_all () - يقوم بالبحث الشامل باستخدام تعبيرات منتظمة
- preg_quote () - يأخذ قالبًا ويعيد نسخته الهاربة
- preg_replace () - يقوم بإجراء عملية بحث واستبدال
- preg_replace_callback () - يؤدي أيضًا عملية بحث واستبدال ، لكنهم يستخدمون رد الاتصال - وظيفة لأي بديل محدد
- preg_split () - يقسم سلسلة أحرف إلى سلاسل فرعية
i
التعديل
i
لترتيب التطابقات دون حساسية لحالة الأحرف.
باستخدام معدّل
m
، يمكنك تنشيط وضع معالجة النصوص متعدد الأسطر.
يمكن حساب استبدال السلاسل كرمز PHP. لتنشيط هذا الوضع ، استخدم أداة تعديل
البريد .
تدعم كل
preg_split()
preg_replace()
و
preg_replace_callback()
و
preg_split()
وسيطة إضافية تقدم قيودًا على الحد الأقصى لعدد البدائل أو الأقسام.
يمكن الإشارة إلى الروابط الخلفية بواسطة علامة $ (على سبيل المثال ، $ 1) ، وفي الإصدارات السابقة ، يتم استخدام علامات \\ بدلاً من علامة $.
لا يتم استخدام الحروف الأولية \ E و \ l و \ L و \ u و \ U (لذلك ، لم يتم ذكرها في هذه المقالة).
ستكون مقالتنا غير مكتملة بدون فئات أحرف POSIX ، والتي تعمل أيضًا في PHP (وبشكل عام قد تزيد من سهولة قراءة النظامي الخاص بك ، ولكن ليس كلهم في عجلة من أمرهم للتعلم ، لأنهم غالبًا ما يكسرون منطق التعبير).
في النهاية ، سأقدم مثالًا عن التنفيذ الملموس للتعبيرات المنتظمة في PHP ، باستخدام التطبيقات المذكورة أعلاه. لقد أضفت أيضًا التحقق من صحة اسم المستخدم حتى لا يتمكن من إدخال مجموعات قصيرة جدًا من الحروف (حسنًا ، افترض أن هذه أسماء مستعارة وليست أسماء وأسماء أقصر من حرفين):
$pattern_name = '/\w{3,}/'; $pattern_mail = '/\w+@\w+\.\w+/'; $pattern_password = '/^(?=.*[az])(?=.*[AZ])(?=.*\d)[a-zA-Z\d]{8,}$/'; if (preg_match($pattern_name, $name) && preg_match($pattern_mail, $mail) && preg_match($pattern_password, $_POST['password'])) {
شكرا لكم جميعا على اهتمامكم! بالطبع ، لقد تطرقنا اليوم إلى جزء فقط من التعبيرات العادية ، ويمكن كتابة بعض المقالات الأخرى عنها. على سبيل المثال ، لم نتحدث عن تنفيذ البحث عن تكرار الكلمات المتطابقة في النص. ولكني آمل أن تكون المعرفة المكتسبة كافية لكتابة التحقق من صحة النموذج الأول بشكل مجدي وبعد ذلك فقط الانتقال إلى أشياء أكثر غضبًا.
حسب التقاليد ، بعض الروابط المفيدة:MIT العادية
ورقة الغش التعبير
الجزء الرسمي من
وثائق php regex.
هذا كل شيء. نراكم في مكثفة !في اليوم الثاني من مكثفة سيعقد هنا