قائمة طعام
مجانا
التسجيل
الصفحة الرئيسية  /  البرامج / تعابير يونكس العادية. استخدام التعبيرات العادية (regex) في Linux

تعابير يونكس العادية. استخدام التعبيرات العادية (regex) في Linux

الأصل: Linux Fundamentals
المؤلف: بول كوبوت
تاريخ النشر: 16 أكتوبر 2014
ترجمة: أ. بانين
تاريخ التحويل: 17 ديسمبر 2014

الفصل 19. التعبيرات العادية

يعد محرك التعبير العادي أداة قوية جدًا في نظام Linux. التعبيرات العادية يمكن استخدامه مع العديد من البرامج مثل bash و vi و rename و grep و sed وغيرها.

يقدم هذا الفصل معلومات أساسية حول التعبيرات النمطية.

إصدارات بناء جملة التعبير العادي

هناك ثلاثة إصدارات مختلفة من بناء جملة التعبير العادي: BRE: Basic Regular Expressions ERE: Extended Regular Expressions PCRE: Perl Regular Expressions (لغة برمجة Perl بنية التعبير العادي)

يمكن استخدام واحد أو أكثر من الصيغ المذكورة اعتمادًا على الأداة المستخدمة.

على سبيل المثال ، تدعم أداة grep الخيار -E لفرض استخدام صيغة التعبير العادي الموسعة (ERE) عند تحليل تعبير عادي ، بينما يفرض الخيار -G استخدام صيغة التعبير العادي الأساسية (BRE) ، بينما يفعل الخيار -P لغة برمجة بيرل (PCRE).

لاحظ أن grep يدعم أيضًا الخيار -F لقراءة التعبير العادي دون معالجة.

تدعم أداة sed أيضًا الخيارات للسماح لك باختيار بنية التعبيرات العادية.

اقرأ دائمًا صفحات الدليل للأدوات التي تستخدمها!

فائدة Grep

إخراج السلاسل التي تتطابق مع النمط

الأداة المساعدة grep هي أداة شائعة لنظام Linux للعثور على السلاسل التي تطابق نمطًا معينًا. فيما يلي أمثلة لأبسط التعبيرات النمطية التي يمكن استخدامها عند العمل بها.

هذا هو محتوى ملف الاختبار المستخدم في الأمثلة. يحتوي هذا الملف على ثلاثة أسطر (أو ثلاثة أسطر جديدة). [البريد الإلكتروني محمي]: ~ اسم القط تانيا لورا فالنتينا

عند البحث عن حرف واحد ، سيتم عرض تلك السلاسل التي تحتوي على الحرف المحدد فقط. [البريد الإلكتروني محمي]: ~ $ grep u أسماء لورا [البريد الإلكتروني محمي]: ~ $ grep e أسماء فالنتينا [البريد الإلكتروني محمي]: ~ $ grep أسمي تانيا فالنتينا

المقارنة مع النمط المستخدم في هذا المثال واضحة ؛ في حالة حدوث حرف معين في سلسلة ، سيقوم grep بطباعة هذه السلسلة.

الجمع بين الشخصيات

للبحث عن مجموعات من الأحرف في السلاسل ، يجب أن تكون أحرف التعبير العادي متسلسلة بنفس الطريقة.

يوضح هذا المثال كيفية عمل الأداة المساعدة grep ، والتي بموجبها سيتطابق التعبير النمطي ia مع السلسلة Tan ia ، ولكن ليس السلسلة V a lent i na ، والتعبير العادي في - السلسلة Valent in a ، ولكن ليس السلسلة T ni a. [البريد الإلكتروني محمي]: ~ $ grep a أسماء تانيا لورا فالنتينا [البريد الإلكتروني محمي]: ~ $ grep ia أسماء تانيا [البريد الإلكتروني محمي]: ~ $ grep في أسماء فالنتينا [البريد الإلكتروني محمي]:~$

واحد أو رمز آخر

يمكن لكل من بناء جملة PCRE وبناء جملة ERE استخدام رمز إنشاء الأنبوب ، والذي سيمثل في هذه الحالة عملية OR منطقية. في هذا المثال ، سنستخدم الأداة المساعدة grep للبحث عن الأسطر التي تحتوي على حرف i أو حرف. [البريد الإلكتروني محمي]: ~ قائمة القطط $ تانيا لورا [البريد الإلكتروني محمي]: ~ $ grep -E "i | a" قائمة تانيا لورا

لاحظ أننا نستخدم الخيار -E لفرض تفسير تعبيرنا العادي كتعبير باستخدام Extended Regular Expression Syntax (ERE).

سيتعين علينا الهروب من الأنبوب إنشاء حرف في تعبير عادي باستخدام صيغة التعبير العادي الأساسي (BRE) لتفسير الأنبوب على أنه OR منطقي بنفس الطريقة. [البريد الإلكتروني محمي]: ~ $ grep -G قائمة "i | a" [البريد الإلكتروني محمي]: ~ $ grep -G "i \\ | a" قائمة تانيا لورا

مباراة أو أكثر

يطابق الحرف * صفرًا أو تكرارًا واحدًا أو أكثر للحرف السابق ، ويتطابق الحرف + مع الحرف التالي. [البريد الإلكتروني محمي]: ~ $ cat list2 ll lol lool loool [البريد الإلكتروني محمي]: ~ $ grep -E "o *" list2 ll lol lool loool [البريد الإلكتروني محمي]: ~ $ grep -E "o +" list2 lol lool loool [البريد الإلكتروني محمي]:~$

نهاية المباراة

في الأمثلة التالية سوف نستخدم هذا الملف: [البريد الإلكتروني محمي]: ~ أسماء القطط $ Tania Laura Valentina Fleur Floor

يوضح المثالان أدناه تقنية استخدام علامة الدولار للعثور على تطابق في نهاية سلسلة. [البريد الإلكتروني محمي]: ~ $ grep a $ names Tania Laura Valentina [البريد الإلكتروني محمي]: ~ $ grep r $ أسماء فلور فلور

تطابق في بداية السطر

تسمح لك علامة الإقحام (^) بالبحث عن تطابق في بداية (أو الأحرف الأولى) من السلسلة.

تستخدم هذه الأمثلة الملف المذكور أعلاه. [البريد الإلكتروني محمي]: ~ $ grep ^ Val أسماء فالنتينا [البريد الإلكتروني محمي]: ~ $ grep ^ F أسماء فلور فلور

تسمى الأحرف الدولار والإدخالات المستخدمة في التعبيرات العادية باسم الارتساء.

تقسيم الكلمات

لا يعد الهروب من كلمات البحث بمسافات حلاً جيدًا (حيث يمكن أيضًا استخدام الأحرف الأخرى كفواصل للكلمات). يوضح المثال أدناه أسلوبًا لاستخدام تسلسل الأحرف \\ b للبحث عن سلاسل بكلمة معينة ، بدلاً من تسلسل أحرف: [البريد الإلكتروني محمي]: ~ $ grep \\ bover \\ b text انتهى الشتاء. هل يمكنك الوصول إلى هناك؟ [البريد الإلكتروني محمي]:~$

لاحظ أن grep يدعم أيضًا الخيار -w لعمليات البحث عن الكلمات. [البريد الإلكتروني محمي]: ~ $ cat text الحاكم هو الحاكم. انتهى الشتاء. هل يمكنك الوصول إلى هناك؟ [البريد الإلكتروني محمي]: ~ $ grep -w over text انتهى الشتاء. هل يمكنك الوصول إلى هناك؟ [البريد الإلكتروني محمي]:~$

خيارات Grep

في بعض الأحيان يكون من الأسهل دمج تعبير عادي بسيط مع خيارات grep بدلاً من إنشاء تعبير عادي أكثر تعقيدًا. تمت مناقشة هذه الخيارات سابقًا: grep -i grep -v grep -w grep -A5 grep -B5 grep -C5

منع الصدفة من توسيع التعبير العادي

رمز الدولار هو رمز خاص لكل من التعبيرات العادية والأصداف (فكر في متغيرات الصدفة والأصداف المضمنة). لذلك ، يوصى بإفلات التعبيرات العادية في جميع الظروف ، لأن الهروب من التعبير العادي يمنع الصدفة من توسيع هذا التعبير. [البريد الإلكتروني محمي]: ~ أسماء $ grep "r $" إعادة تسمية Fleur Floor

إعادة تسمية الأداة

إعادة تسمية تطبيقات الأداة المساعدة

في توزيعة Debain Linux ، يحتوي المسار / usr / bin / rename على ارتباط إلى البرنامج النصي / usr / bin / prename المثبت من حزمة perl. [البريد الإلكتروني محمي] ~ $ dpkg -S $ (readlink -f $ (الذي يعيد التسمية)) perl: / usr / bin / prename

لا تنشئ التوزيعات المستندة إلى Red Hat رابطًا رمزيًا مشابهًا للإشارة إلى البرنامج النصي الموصوف (باستثناء ، بالطبع ، عند إنشاء ارتباط رمزي لبرنامج نصي مثبت يدويًا) ، لذلك لن يصف هذا القسم تنفيذ الأداة المساعدة لإعادة التسمية من توزيع ريد هات.

في المناقشات حول الأداة المساعدة لإعادة التسمية على الإنترنت ، يحدث الارتباك عادةً بسبب حقيقة أن الحلول التي تعمل بشكل مثالي في توزيع دبيان (بالإضافة إلى Ubuntu و xubuntu و Mint ...) لا يمكن استخدامها في توزيع Red Hat (بالإضافة إلى CentOS ، فيدورا، ...).

حزمة بيرل

يتم تنفيذ الأمر rename بالفعل كبرنامج نصي باستخدام التعبيرات العادية للغة برمجة perl. يمكن العثور على دليل كامل لاستخدام هذا البرنامج النصي بعد إدخال أمر perldoc perlrequick (بعد تثبيت حزمة perldoc). [البريد الإلكتروني محمي]: ~ # aptitude install perl-doc سيتم تثبيت الحزم الجديدة التالية: تم تحديث حزم perl-doc 0 ، وتثبيت حزمة جديدة واحدة ، و 0 حزم محددة للإزالة ، و 0 لم يتم تحديث الحزم. تحتاج إلى الحصول على 8170 كيلوبايت من المحفوظات. بعد تفريغ 13.2 ميغا بايت سيتم استخدامها. احصل على: 1 http://mirrordirector.raspbian.org/raspbian/ wheezy / main perl-do ... تم استلام 8،170 كيلو بايت في 19 ثانية (412 كيلو بايت / ثانية) حدد حزمة perl-doc غير المحددة سابقًا. (قراءة قاعدة البيانات ... على هذه اللحظة تثبيت ملفات ودليل 67121.) تفريغ perl-doc (من ... / perl-doc_5.14.2-21 + rpi2_all.deb) ... إضافة "تحويل / usr / bin / perldoc إلى / usr / bin / perldoc. stub by perl-doc "مشغلات المعالجة لـ man-db ... تكوين حزمة perl-doc (5.14.2-21 + rpi2) ... [البريد الإلكتروني محمي]: ~ # perlrequick بيرلريك

النحو المعروف

الاستخدام الأكثر شيوعًا لأداة إعادة التسمية المساعدة هو البحث عن الملفات ذات الأسماء التي تطابق نمطًا معينًا في شكل سلسلة ، واستبدال هذه السلسلة بسلسلة أخرى.

عادة ، يتم وصف هذا الإجراء باستخدام التعبير العادي s / string / another string / ، كما هو موضح في المثال: [البريد الإلكتروني محمي] ~ $ ls abc allfiles.TXT bllfiles.TXT Scratch Tennis2.TXT abc.conf النسخ الاحتياطي cllfiles.TXT temp.TXT Tennis.TXT [البريد الإلكتروني محمي] ~ $ إعادة تسمية "s / TXT / text /" * [البريد الإلكتروني محمي] ~ $ ls abc allfiles.text bllfiles.text خدش Tennis2.text abc.conf النسخ الاحتياطي cllfiles.text temp.text Tennis.text

وفيما يلي مثال آخر يستخدم الصيغة المعروفة لأداة إعادة التسمية لإعادة تعديل امتدادات نفس الملفات: [البريد الإلكتروني محمي] ~ $ ls abc allfiles.text bllfiles.text خدش Tennis2.text abc.conf النسخ الاحتياطي cllfiles.text temp.text Tennis.text [البريد الإلكتروني محمي] ~ $ أعد تسمية "s / text / txt /" * .text [البريد الإلكتروني محمي] ~ $ ls abc allfiles.txt bllfiles.txt سكراتش Tennis2.txt abc.conf النسخ الاحتياطي cllfiles.txt temp.txt Tennis.txt [البريد الإلكتروني محمي] ~ $

يمكن استخدام هذين المثالين لأن السلاسل التي نستخدمها تظهر حصريًا في امتدادات الملفات. ضع في اعتبارك أن امتدادات الملفات ليست ذات صلة عند استخدام bash shell.

يوضح المثال التالي مشكلة قد تواجهها عند استخدام بناء الجملة هذا. [البريد الإلكتروني محمي] ~ $ المس atxt.txt [البريد الإلكتروني محمي] ~ $ أعد تسمية "s / txt / problem /" atxt.txt [البريد الإلكتروني محمي] ~ $ ls abc allfiles.txt نسخة احتياطية cllfiles.txt temp.txt Tennis.txt abc.conf aproblem.txt bllfiles.txt Scratch Tennis2.txt [البريد الإلكتروني محمي] ~ $

عند تنفيذ الأمر المعني ، يتم استبدال التكرار الأول فقط للسلسلة التي تم البحث عنها.

الاستبدال العالمي

يمكن وصف الصيغة المستخدمة في المثال السابق على النحو التالي: s / regex / replace string /. هذا الوصف بسيط ومباشر ، حيث لا يتعين عليك سوى وضع تعبير عادي بين الشرطتين المائلتين الأوليين وسلسلة الاستبدال بين آخر شرطتين مائلتين.

يوسع المثال التالي بناء الجملة هذا قليلاً عن طريق إضافة معدل. [البريد الإلكتروني محمي] ~ $ rename -n "s / TXT / txt / g" aTXT.TXT aTXT.TXT تمت إعادة تسميته ليصبح atxt.txt [البريد الإلكتروني محمي] ~ $

يمكن الآن وصف البنية التي نستخدمها بأنها s / تعبير عادي / سلسلة استبدال / g ، حيث يشير مُعدِّل s إلى عملية تبديل ، ويشير مُعدِّل g إلى الحاجة إلى التنفيذ الاستبدال العالمي (عالمي).

لاحظ أنه في هذا المثال ، تم استخدام الخيار -n لعرض معلومات حول العملية التي يتم إجراؤها (بدلاً من إجراء العملية نفسها ، وهي إعادة تسمية الملف مباشرةً).

استبدال غير حساس لحالة الأحرف

معدل آخر قد تجده مفيدًا هو i modifier. يوضح المثال أدناه تقنية لاستبدال سلسلة بسلسلة أخرى بطريقة غير حساسة لحالة الأحرف. [البريد الإلكتروني محمي]: ~ / files $ ls file1.text file2.TEXT file3.txt [البريد الإلكتروني محمي]: ~ / files $ rename "s / .text / .txt / i" * [البريد الإلكتروني محمي]: ~ / files $ ls file1.txt file2.txt file3.txt [البريد الإلكتروني محمي]: ~ / ملفات $

تغيير الامتدادات

واجهة القيادة سلاسل لينكس ليس لديه فكرة عن امتدادات الملفات المشابهة لتلك المستخدمة في نظام التشغيل MS-DOS ، لكن العديد من المستخدمين وتطبيقات واجهة المستخدم الرسومية يستخدمونها.

يقدم هذا القسم مثالاً على استخدام الأداة المساعدة لإعادة التسمية لتغيير امتدادات الملفات فقط. يستخدم المثال علامة الدولار للإشارة إلى أن نهاية اسم الملف هي نقطة البداية للاستبدال. [البريد الإلكتروني محمي] ~ $ ls * .txt allfiles.txt bllfiles.txt cllfiles.txt really.txt.txt temp.txt Tennis.txt [البريد الإلكتروني محمي] ~ $ أعد تسمية "s / .txt $ /. TXT /" * .txt [البريد الإلكتروني محمي] ~ $ ls * .TXT allfiles.TXT bllfiles.TXT cllfiles.TXT really.txt.TXT temp.TXT Tennis.TXT [البريد الإلكتروني محمي] ~ $

لاحظ أن علامة الدولار في التعبير العادي تشير إلى نهاية السطر. بدون علامة الدولار ، يجب أن يفشل تنفيذ هذا الأمر عند معالجة اسم الملف really.txt.txt.

فائدة Sed

محرر تدفق البيانات

يستخدم محرر الدفق ، أو sed للاختصار ، التعبيرات العادية لتعديل تدفق البيانات.

في هذا المثال ، يتم استخدام sed لاستبدال سلسلة. صدى الاثنين | Sed "s / Monday / Tuesday /" الثلاثاء

يمكن استبدال الخطوط المائلة ببعض الأحرف الأخرى ، والتي قد تكون أكثر ملاءمة وتحسن إمكانية قراءة الأمر في بعض الحالات. صدى الاثنين | sed "s: الاثنين: الثلاثاء: صدى الثلاثاء الاثنين | Sed "s_Week_Tue_" صدى الثلاثاء الاثنين | sed "s | الاثنين | الثلاثاء |" الثلاثاء

محرر تفاعلي

على الرغم من أن sed مصمم للتعامل مع تدفقات البيانات ، إلا أنه يمكن استخدامه أيضًا لمعالجة الملفات بشكل تفاعلي. [البريد الإلكتروني محمي]: ~ / files $ echo Monday\u003e today [البريد الإلكتروني محمي]: ~ / files $ cat اليوم الاثنين [البريد الإلكتروني محمي]: ~ / files $ sed -i "s / Monday / Tuesday /" اليوم [البريد الإلكتروني محمي]: ~ / files $ قطة اليوم الثلاثاء

يمكن استخدام حرف العطف للإشارة إلى سلسلة البحث (والعثور عليها).

في هذا المثال ، يتم استخدام علامة العطف لمضاعفة عدد الصفوف الموجودة. صدى الاثنين | sed "s / Monday / && /" صدى MondayMonday Monday | sed "s / nick / && /" الاثنين

يتم استخدام الأقواس لتجميع أجزاء من تعبير عادي يمكن الرجوع إليها لاحقًا.

تأمل المثال التالي: [البريد الإلكتروني محمي]: ~ صدى يوم الأحد | sed "s _ \\ (Sun \\) _ \\ 1ny_" Sunnyday [البريد الإلكتروني محمي]: ~ صدى يوم الأحد | sed "s _ \\ (Sun \\) _ \\ 1ny \\ 1_" الأحد المشمس

فترة للدلالة على أي حرف

في التعبير العادي ، يمكن أن يمثل حرف نقطة بسيط أي حرف. [البريد الإلكتروني محمي]: ~ $ echo 2014-04-01 | sed "s / .....-..-../ YYYY-MM-DD /" YYYY-MM-DD [البريد الإلكتروني محمي]: ~ $ echo abcd-ef-gh | sed "s / .....-..-../ YYYY-MM-DD /" YYYY-MM-DD

إذا تم استخدام أكثر من زوج واحد من الأقواس ، فيمكن الإشارة إلى كل منها باستخدام قيم رقمية متتالية. [البريد الإلكتروني محمي]: ~ $ echo 2014-04-01 | sed "s / \\ (.... \\) - \\ (.. \\) - \\ (.. \\) / \\ 1+ \\ 2+ \\ 3 /" 2014 + 04 + 01 [البريد الإلكتروني محمي]: ~ $ echo 2014-04-01 | sed "s / \\ (.... \\) - \\ (.. \\) - \\ (.. \\) / \\ 3: \\ 2: \\ 1 /" 01: 04: 2014

هذه الميزة تسمى التجميع.

الفراغ

يمكن استخدام تسلسل الأحرف \\ s للإشارة إلى حرف مثل مسافة أو حرف جدولة.

يبحث هذا المثال بشكل عام عن تسلسل أحرف المسافات (\\ s) التي تم استبدالها بحرف مسافة واحد. [البريد الإلكتروني محمي]: ~ $ echo -e "اليوم \\ t \\ t \\ t" اليوم يوم دافئ [البريد الإلكتروني محمي]: ~ $ echo -e "إنه \\ t دافئ \\ t يوم" | sed "s_ \\ s_ _g" اليوم يوم دافئ

تكرارات اختيارية

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

يبحث المثال أدناه عن سلسلة من ثلاث نقاط ، مع كون الحرف الثالث اختياريًا. [البريد الإلكتروني محمي]: ~ $ cat list2 ll lol lool loool [البريد الإلكتروني محمي]: ~ $ grep -E "ooo؟" list2 lool loool [البريد الإلكتروني محمي]: ~ $ cat list2 | sed "s / ooo \\؟ / A /" ll ll all lAl

بالضبط ن ممثلين

يمكنك تحديد العدد الدقيق لتكرار الحرف السابق.

يبحث هذا المثال عن سلاسل تتكون من ثلاثة أحرف بالضبط. [البريد الإلكتروني محمي]: ~ $ cat list2 ll lol lool loool [البريد الإلكتروني محمي]: ~ $ grep -E "o (3)" list2 loool [البريد الإلكتروني محمي]: ~ $ cat list2 | sed "s / o \\ (3 \\) / A /" ll lool lAl [البريد الإلكتروني محمي]:~$

N إلى m التكرار

وفي هذا المثال ، نشير بوضوح إلى وجوب تكرار الرمز من الحد الأدنى (2) إلى الحد الأقصى (3) من المرات. [البريد الإلكتروني محمي]: ~ $ cat list2 ll lol lool loool [البريد الإلكتروني محمي]: ~ $ grep -E "o (2،3)" list2 lool loool [البريد الإلكتروني محمي]: ~ $ grep "o \\ (2،3 \\)" list2 lool loool [البريد الإلكتروني محمي]: ~ $ cat list2 | sed "s / o \\ (2،3 \\) / A /" ll lol lAl [البريد الإلكتروني محمي]:~$

تاريخ شل باش

يمكن لقشرة bash أيضًا تفسير بعض التعبيرات النمطية.

يوضح هذا المثال أسلوبًا لمعالجة علامة التعجب داخل قناع البحث في محفوظات bash shell. [البريد الإلكتروني محمي]: ~ $ mkdir اصمت [البريد الإلكتروني محمي]: ~ $ cd اصمت / [البريد الإلكتروني محمي]: ~ / hist $ touch file1 file2 file3 [البريد الإلكتروني محمي]: ~ / hist $ ls -l file1 -rw-r - r-- 1 Paul Paul أبريل 0 15 22:07 file1 [البريد الإلكتروني محمي]: ~ / hist $! l ls -l file1 -rw-r - r-- 1 Paul Paul 0 أبريل 15 22:07 file1 [البريد الإلكتروني محمي]: ~ / اصمت $! l: s / 1/3 ls -l file3 -rw-r - r-- 1 بول بول 0 أبريل 15 22:07 ملف 3 [البريد الإلكتروني محمي]: ~ / اصمت $

تعمل هذه التقنية أيضًا عند استخدام الأرقام عند قراءة محفوظات أوامر قذيفة bash. [البريد الإلكتروني محمي]: ~ / Hist $ history 6 2089 mkdir hist 2090 cd hist / 2091 touch file1 file2 file3 2092 ls -l file1 2093 ls -l file3 2094 history 6 [البريد الإلكتروني محمي]: ~ / اصمت $! 2092 ls -l file1 -rw-r - r-- 1 بول بول 0 أبريل 15 22:07 ملف 1 [البريد الإلكتروني محمي]: ~ / اصمت $! 2092: s / 1/2 ls -l file2 -rw-r - r-- 1 بول بول 0 أبريل 15 22:07 ملف 2 [البريد الإلكتروني محمي]: ~ / اصمت $

من أجل معالجة النصوص بشكل كامل في نصوص bash باستخدام sed و awk ، ما عليك سوى فهم التعبيرات العادية. يمكن العثور على تطبيقات هذه الأداة الأكثر فائدة حرفيًا في كل مكان ، وعلى الرغم من أن جميع التعبيرات العادية مرتبة بطريقة مماثلة ، بناءً على نفس الأفكار ، إلا أن العمل معها له خصائص معينة في بيئات مختلفة. هنا سنتحدث عن التعبيرات النمطية المناسبة للاستخدام في البرامج النصية. سطر الأوامر لينكس.

تهدف هذه المادة إلى أن تكون مقدمة للتعبيرات العادية لأولئك الذين قد لا يعرفون ما هي على الإطلاق. لذلك لنبدأ من البداية.

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

بالنسبة للكثيرين ، عندما يرون التعبيرات العادية لأول مرة ، فإنهم يعتقدون على الفور أنهم أمام خليط لا معنى له من الشخصيات. لكن هذا بالطبع بعيد كل البعد عن الواقع. ألق نظرة على هذا التعبير العادي على سبيل المثال


في رأينا ، حتى المبتدئ تمامًا سوف يفهم على الفور كيف يعمل ولماذا تحتاجه :) إذا كنت لا تفهم تمامًا ، فما عليك سوى القراءة وستجد كل شيء في مكانه الصحيح.
التعبير العادي هو نمط تستخدمه برامج مثل sed أو awk لتصفية النص. تستخدم القوالب أحرف ASCII العادية لتمثيل نفسها ، وما يسمى بالحروف الأولية ، والتي تلعب دورًا خاصًا ، على سبيل المثال ، مما يسمح لك بالإشارة إلى مجموعات معينة من الأحرف.

أنواع التعبير العادي

تطبيقات التعبير العادي في بيئات مختلفة ، مثل لغات البرمجة مثل Java و Perl و Python وأدوات Linux مثل sed و awk و grep ، لها بعض المراوغات. تعتمد هذه الميزات على ما يسمى بمحركات regex التي تفسر الأنماط.
لينكس لديه محركان للتعبير العادي:
  • محرك يدعم معيار POSIX Basic Regular Expression (BRE).
  • محرك يدعم معيار POSIX Extended Regular Expression (ERE).
تتوافق معظم أدوات Linux المساعدة على الأقل مع معيار POSIX BRE ، لكن بعض الأدوات المساعدة (بما في ذلك sed) لا تفهم سوى مجموعة فرعية من معيار BRE. أحد أسباب هذا القيد هو الرغبة في جعل هذه الأدوات المساعدة في أسرع وقت ممكن في معالجة الكلمات.

غالبًا ما يتم تنفيذ معيار POSIX ERE في لغات البرمجة. يتيح لك استخدام الكثير من الأدوات عند تصميم التعبيرات العادية. على سبيل المثال ، يمكن أن يكون تسلسل أحرف خاصًا للأنماط المستخدمة بشكل متكرر ، مثل البحث في النص كلمات فردية أو مجموعات من الأرقام. يدعم Awk معيار ERE.

هناك العديد من الطرق لتطوير التعبيرات العادية ، اعتمادًا على رأي المبرمج وعلى ميزات المحرك الذي تم إنشاؤه من أجله. ليس من السهل كتابة تعبيرات منتظمة عامة يمكن لأي محرك فهمها. لذلك ، سنركز على التعبيرات النمطية الأكثر استخدامًا ونلقي نظرة على كيفية تنفيذها لـ sed و awk.

التعبيرات العادية POSIX BRE

ربما يكون أبسط نمط BRE هو تعبير عادي للعثور على التواجد الدقيق لسلسلة من الأحرف في النص. هكذا يبدو البحث عن سلسلة sed و awk:

صدى $ "هذا اختبار" | sed -n "/ test / p" $ echo "This is a test" | awk "/ test / (print $ 0)"

البحث عن نص حسب النمط في sed


البحث عن نص حسب النمط في awk

يمكنك ملاحظة أن البحث عن نمط معين يتم تنفيذه دون مراعاة الموقع الدقيق للنص في السلسلة. بالإضافة إلى ذلك ، لا يهم عدد التكرارات. بعد أن يجد التعبير العادي النص المحدد في أي مكان في السلسلة ، تعتبر السلسلة صالحة ويتم تمريرها لمزيد من المعالجة.

عند التعامل مع التعبيرات العادية ، ضع في اعتبارك أنها حساسة لحالة الأحرف:

صدى $ "هذا اختبار" | awk "/ Test / (print $ 0)" $ echo "This is a test" | awk "/ test / (print $ 0)"

التعبيرات العادية حساسة لحالة الأحرف

لم يتطابق التعبير النمطي الأول ، نظرًا لأن كلمة "اختبار" التي تبدأ بحرف كبير لا تظهر في النص. الثانية ، التي تم ضبطها للبحث عن كلمة مكتوبة بأحرف كبيرة ، وجدت سلسلة مطابقة في الدفق.

في التعبيرات العادية ، لا يمكنك استخدام الأحرف فحسب ، بل أيضًا استخدام المسافات والأرقام:

صدى $ "This is a test 2 again" | awk "/ اختبار 2 / (طباعة $ 0)"

البحث عن قطعة نصية تحتوي على مسافات وأرقام

يتم التعامل مع المسافات كأحرف عادية بواسطة محرك regex.

الرموز الخاصة

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

.*^${}\+?|()
إذا كانت هناك حاجة إلى واحد منهم في النمط ، فسوف تحتاج إلى الهروب بشرطة مائلة للخلف (شرطة مائلة للخلف) - \\.

على سبيل المثال ، إذا كنت بحاجة إلى العثور على علامة الدولار في النص ، فيجب تضمينها في القالب ، مسبوقة بحرف هروب. لنفترض أن لديك ملفًا يسمى myfile بالنص التالي:

يوجد 10 دولارات في جيبي
يمكن الكشف عن علامة الدولار باستخدام نمط مثل هذا:

$ awk "/ \\ $ / (طباعة $ 0)" ملفي

استخدام شخصية خاصة في قالب

بالإضافة إلى ذلك ، فإن الشرطة المائلة للخلف هي أيضًا حرف خاص ، لذلك إذا كنت تريد استخدامه في قالب ، فستحتاج إلى الهروب منه أيضًا. يبدو كشرطتين مائلتين للأمام:

صدى $ "\\ شخصية خاصة" | awk "/ \\\\ / (print $ 0)"

الخط المائل للخلف الهروب

على الرغم من عدم تضمين الشرطة المائلة للأمام في قائمة الأحرف الخاصة أعلاه ، فإن محاولة استخدامها في تعبير عادي مكتوب لـ sed أو awk سيؤدي إلى حدوث خطأ:

صدى $ "3/2" | awk "/// (طباعة $ 0)"

استخدام غير صحيح للشرطة المائلة للأمام في قالب

إذا كنت بحاجة إليه ، فستحتاج أيضًا إلى فحصه:

صدى $ "3/2" | awk "/ \\ // (طباعة $ 0)"

الهروب إلى الأمام مائلة

رموز المرساة

يوجد حرفان خاصان لربط نمط ببداية سلسلة نصية أو نهايتها. يسمح لك حرف الغلاف - ^ بوصف تسلسل الأحرف التي تظهر في بداية سطور النص. إذا ظهر النمط الذي تبحث عنه في مكان آخر من السلسلة ، فلن يستجيب التعبير العادي له. يبدو استخدام هذا الرمز كما يلي:

صدى $ مرحبا بكم في موقع likegeeks | awk "/ ^ likegeeks / (print $ 0)" $ echo "likegeeks website" | awk "/ ^ likegeeks / (طباعة $ 0)"

إيجاد نمط في بداية السطر

يُستخدم الرمز ^ للبحث عن نمط في بداية السلسلة ، بينما يتم أخذ الحالة أيضًا في الاعتبار. دعونا نرى كيف يؤثر ذلك على المعالجة ملف نصي:

$ awk "/ ^ هذا / (طباعة $ 0)" ملفي


ابحث عن نمط في بداية السطر في نص من ملف

باستخدام sed ، إذا وضعت غطاءً في أي مكان داخل النموذج ، فسيتم معاملته مثل أي شخصية عادية أخرى:

صدى $ "This ^ is a test" | sed -n "/ s ^ / p"

لا يغطي الغطاء في بداية النمط في sed

في awk ، عند استخدام نفس النمط ، يجب تخطي الحرف المحدد:

صدى $ "This ^ is a test" | awk "/ s \\ ^ / (print $ 0)"

الغلاف ليس في بداية قالب في awk

توصلنا إلى البحث عن أجزاء النص الموجودة في بداية السطر. ماذا لو كنت تريد العثور على شيء ما في نهاية السطر؟

ستساعدنا علامة الدولار - $ ، وهي حرف الربط في نهاية السطر ، في هذا:

صدى $ "هذا اختبار" | awk "/ test $ / (print $ 0)"

البحث عن نص في نهاية السطر

يمكن استخدام كلا حرفي الربط في نفس النمط. دعونا نعالج ملف myfile ، ومحتوياته موضحة في الشكل أدناه ، باستخدام التعبير النمطي التالي:

$ awk "/ ^ this is a test $ / (print $ 0)" myfile


نمط يستخدم أحرفًا خاصة لبداية السطر ونهايته

كما ترى ، يتفاعل النموذج فقط مع سطر مطابق تمامًا تسلسل معين الرموز وموقعها.

إليك كيفية تصفية الأسطر الفارغة باستخدام أحرف الربط:

$ awk "! / ^ $ / (print $ 0)" myfile
في هذا النموذج ، استخدمت حرف النفي ، علامة التعجب -! ... باستخدام هذا النمط ، يبحث عن سلاسل لا تحتوي على أي شيء بين بداية السلسلة ونهايتها ، وبفضل علامة تعجب تتم طباعة الأسطر التي لا تتطابق مع هذا النمط فقط.

رمز النقطة

يتم استخدام النقطة للبحث عن أي حرف مفرد باستثناء سطر التغذية. دعنا نمرر ملف myfile إلى مثل هذا التعبير العادي ، ومحتوياته موضحة أدناه:

$ awk "/.st/(print $ 0)" ملفي


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

كما ترى من الإخراج ، يتطابق أول سطرين فقط من الملف مع النمط ، نظرًا لاحتوائهما على تسلسل الأحرف "st" ، يسبقه حرف آخر ، بينما السطر الثالث لا يحتوي على تسلسل مناسب ، وفي السطر الرابع يكون كذلك ، ولكنه موجود بداية السطر.

فئات الشخصية

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

بفضل هذا النهج ، يمكنك تنظيم بحث عن أي شخصية من مجموعة معينة. تستخدم الأقواس المربعة لوصف فئة الأحرف -:

$ awk "/ th / (print $ 0)" myfile


وصف فئة أحرف التعبير العادي

نحن هنا نبحث عن سلسلة من الأحرف "th" مسبوقة بالحرف "o" أو الحرف "i".

تكون الفصول الدراسية مفيدة عند البحث عن الكلمات التي يمكن أن تبدأ بأحرف كبيرة وصغيرة:

صدى $ "هذا اختبار" | awk "/ his is a test / (print $ 0)" $ echo "This is a test" | awk "/ his is a test / (print $ 0)"

ابحث عن الكلمات التي يمكن أن تبدأ بحرف صغير أو كبير

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

نفي فئات الشخصية

يمكن أيضًا استخدام فئات الأحرف لحل المشكلة المعاكسة الموضحة أعلاه. أي ، بدلاً من البحث عن الرموز المدرجة في الفصل ، يمكنك تنظيم بحث عن كل شيء غير موجود في الفصل. لتحقيق هذا السلوك الخاص بالتعبير النمطي ، يجب وضع ^ أمام قائمة الأحرف الخاصة بالفئة. تبدو هكذا:

$ awk "/ [^ oi] th / (print $ 0)" myfile


ابحث عن شخصيات خارج الفصل

في هذه الحالة ، سيتم العثور على تسلسل من الأحرف "th" ، والتي لا يوجد قبلها "o" ولا "i".

نطاقات من الشخصيات

في فئات الأحرف ، يمكنك وصف نطاقات من الأحرف باستخدام شرطة:

$ awk "/ st / (print $ 0)" myfile


وصف مجموعة من الشخصيات في فئة الشخصية

في هذا المثال ، يستجيب التعبير النمطي لتسلسل الأحرف "st" مسبوقًا بأي حرف يقع ، بترتيب أبجدي ، بين الحرفين "e" و "p".

يمكن أيضًا إنشاء النطاقات من الأرقام:

صدى دولار "123" | awk "//" $ echo "12a" | awk "//"

تعبير عادي لإيجاد أي ثلاثة أعداد

يمكن تضمين عدة نطاقات في فئة الأحرف:

$ awk "/ st / (print $ 0)" myfile


فئة أحرف تتكون من نطاقات متعددة

سيطابق هذا التعبير العادي جميع السلاسل التي تسبقها أحرف في النطاقين a-f و m-z.

فئات الشخصيات الخاصة

يحتوي BRE على فئات أحرف خاصة يمكنك استخدامها عند كتابة التعبيرات العادية:
  • [[: alpha:]] - تتطابق مع أي حرف أبجدي كبير أو صغير.
  • [[: alnum:]] - يتطابق مع أي حرف أبجدي رقمي ، أي الأحرف الموجودة في النطاقات 0-9 ، A-Z ، a-z.
  • [[: blank:]] - تطابق مسافة وعلامة تبويب.
  • [[: digit:]] - أي حرف رقمي من 0 إلى 9.
  • [[: upper:]] - حروف أبجدية كبيرة - A-Z.
  • [[: Lower:]] - أحرف أبجدية صغيرة - a-z.
  • [[: print:]] - تطابق أي حرف قابل للطباعة.
  • [[: punct:]] - تطابق علامات الترقيم.
  • [[: space:]] - أحرف المسافات البيضاء ، على وجه الخصوص - أحرف المسافة ، الجدولة ، NL ، FF ، VT ، CR.
يمكنك استخدام فئات خاصة في قوالب مثل هذا:

صدى $ "abc" | awk "/ [[: alpha:]] / (print $ 0)" $ echo "abc" | awk "/ [[: digit:]] / (print $ 0)" $ echo "abc123" | awk "/ [[: digit:]] / (print $ 0)"


فئات الأحرف الخاصة في التعبيرات العادية

رمز النجمة

إذا قمت بوضع علامة النجمة بعد حرف في النمط ، فهذا يعني أن التعبير العادي سيعمل إذا ظهر الحرف في السلسلة لأي عدد من المرات - بما في ذلك الموقف عندما يكون الحرف غير موجود في السلسلة.

صدى $ "اختبار" | awk "/ tes * t / (print $ 0)" $ echo "tessst" | awk "/ tes * t / (print $ 0)"


استخدام الحرف * في التعبيرات العادية

عادةً ما يُستخدم حرف البدل هذا للعمل مع الكلمات التي تحتوي على أخطاء إملائية باستمرار ، أو للكلمات التي يمكن تهجئتها بشكل مختلف:

صدى $ "أحب اللون الأخضر" | awk "/ colou * r / (print $ 0)" $ echo "أحب اللون الأخضر" | awk "/ colou * r / (print $ 0)"

ابحث عن كلمة لها تهجئات مختلفة

في هذا المثال ، يتفاعل التعبير العادي نفسه مع كل من كلمة "color" وكلمة "color". ويرجع ذلك إلى حقيقة أن الرمز "u" ، وبعده توجد علامة النجمة ، يمكن أن يكون إما غائبًا أو يظهر عدة مرات على التوالي.

ميزة أخرى مفيدة تنشأ من خصائص رمز النجمة هي دمجها مع نقطة. تسمح هذه المجموعة للتعبير العادي بالرد على أي عدد من الأحرف:

$ awk "/this.*test/ (طباعة $ 0)" myfile


قالب يستجيب لأي عدد من أي حرف

في هذه الحالة ، لا يهم كم وما هي الأحرف بين الكلمتين "هذا" و "اختبار".

يمكن أيضًا استخدام علامة النجمة مع فئات الأحرف:

صدى دولار "ش" | awk "/ s * t / (print $ 0)" $ echo "sat" | awk "/ s * t / (print $ 0)" $ echo "set" | awk "/ s * t / (طباعة $ 0)"


استخدام علامة النجمة مع فئات الأحرف

في جميع الأمثلة الثلاثة ، يعمل التعبير العادي لأن علامة النجمة بعد فئة الحرف تعني أنه إذا تم العثور على أي عدد من الأحرف "a" أو "e" ، أو إذا تعذر العثور عليها ، فستتطابق السلسلة مع النمط المحدد.

التعبيرات العادية POSIX ERE

القوالب معيار POSIX قد تحتوي EREs التي تدعمها بعض أدوات Linux المساعدة على أحرف إضافية. كما ذكرنا سابقًا ، يدعم awk هذا المعيار ، لكن sed لا يدعمه.

هنا سنلقي نظرة على الرموز الأكثر استخدامًا في أنماط ERE ، والتي ستكون مفيدة عند إنشاء التعبيرات العادية الخاصة بك.

▍ علامة استفهام

تشير علامة الاستفهام إلى أن الحرف السابق قد يظهر مرة واحدة في النص أو لا يظهر على الإطلاق. هذه الشخصية هي واحدة من أحرف التكرار الأولية. وهنا بعض الأمثلة:

صدى $ "tet" | awk "/ tes؟ t / (print $ 0)" $ echo "test" | awk "/ tes؟ t / (print $ 0)" $ echo "tesst" | awk "/ tes؟ t / (print $ 0)"


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

كما ترى ، في الحالة الثالثة ، يظهر الحرف "s" مرتين ، لذا فإن التعبير النمطي لا يتفاعل مع كلمة "tesst".

يمكن أيضًا استخدام علامة الاستفهام مع فئات الأحرف:

صدى دولار "tst" | awk "/ t؟ st / (print $ 0)" $ echo "test" | awk "/ t؟ st / (print $ 0)" $ echo "tast" | awk "/ t؟ st / (print $ 0)" $ echo "taest" | awk "/ t؟ st / (print $ 0)" $ echo "teest" | awk "/ t؟ st / (print $ 0)"


علامة الاستفهام وفئات الشخصيات

إذا لم يكن هناك أحرف من الفئة في السلسلة ، أو حدث أحدها مرة واحدة ، فسيتم تشغيل التعبير العادي ، ولكن بمجرد ظهور حرفين في الكلمة ، لم يعد النظام يجد تطابقًا للنمط في النص.

▍ رمز زائد

يشير رمز الجمع في النمط إلى أن التعبير العادي سيجد الرمز المطلوب إذا تكرر الحرف السابق مرة واحدة أو أكثر في النص. في الوقت نفسه ، لن يتفاعل هذا البناء مع عدم وجود رمز:

صدى $ "اختبار" | awk "/ te + st / (print $ 0)" $ echo "teest" | awk "/ te + st / (print $ 0)" $ echo "tst" | awk "/ te + st / (طباعة $ 0)"


علامة الجمع في التعبيرات العادية

في هذا المثال ، إذا لم يكن هناك حرف "e" في الكلمة ، فلن يجد محرك regex تطابقًا في النص. يعمل رمز الجمع أيضًا مع فئات الأحرف ، مما يجعله يبدو كعلامة النجمة وعلامة الاستفهام:

صدى دولار "tst" | awk "/ t + st / (print $ 0)" $ echo "test" | awk "/ t + st / (print $ 0)" $ echo "teast" | awk "/ t + st / (print $ 0)" $ echo "teeast" | awk "/ t + st / (طباعة $ 0)"


فئات علامة الجمع والحرف

في هذه الحالة ، إذا كانت السلسلة تحتوي على أي حرف من الفئة ، فسيتم اعتبار النص مطابقًا للنمط.

▍ أقواس الأحرف

تشبه الأقواس المتعرجة التي يمكنك استخدامها في أنماط ERE الأحرف التي تمت مناقشتها أعلاه ، ولكنها تسمح لك بتحديد العدد المطلوب من التكرارات للحرف السابق بدقة أكبر. يمكن تحديد القيد بتنسيقين:
  • n - رقم يحدد العدد الدقيق لمرات الظهور المراد البحث عنها
  • n ، m - رقمان يتم تفسيرهما على النحو التالي: "على الأقل n مرة ، ولكن ليس أكثر من m".
فيما يلي أمثلة على الخيار الأول:

صدى دولار "tst" | awk "/ te (1) st / (print $ 0)" $ echo "test" | awk "/ te (1) st / (print $ 0)"

الأقواس المتعرجة في الأنماط ، ابحث عن عدد التكرارات بالضبط

في الإصدارات الأقدم من awk ، كان عليك استخدام مفتاح سطر أوامر إعادة الفاصل الزمني لكي يتعرف البرنامج على الفواصل الزمنية في التعبيرات العادية ، ولكن في الإصدارات الأحدث ، هذا ليس ضروريًا.

صدى دولار "tst" | awk "/ te (1،2) st / (print $ 0)" $ echo "test" | awk "/ te (1،2) st / (print $ 0)" $ echo "teest" | awk "/ te (1،2) st / (print $ 0)" $ echo "teeest" | awk "/ te (1،2) st / (print $ 0)"


التباعد المحدد في الأقواس المتعرجة

في هذا المثال ، يجب أن يظهر الحرف "e" في السطر 1 أو مرتين ، ثم يتفاعل التعبير العادي مع النص.

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

صدى دولار "tst" | awk "/ t (1،2) st / (print $ 0)" اختبار $ echo "| awk "/ t (1،2) st / (print $ 0)" $ echo "teest" | awk "/ t (1،2) st / (print $ 0)" $ echo "teeast" | awk "/ t (1،2) st / (print $ 0)"


الأقواس المجعدة وفئات الشخصيات

سيتفاعل القالب مع النص إذا كان يحتوي على الحرف "a" أو الحرف "e" مرة أو مرتين.

"أو" الشخصية المنطقية

الرمز | - شريط عمودي ، يعني منطقي "أو" في التعبيرات العادية. عند معالجة تعبير عادي يحتوي على عدة أجزاء مفصولة بهذه العلامة ، سيعتبر المحرك أن النص المحلل مناسبًا إذا كان يطابق أيًا من الأجزاء. هذا مثال:

صدى $ "هذا اختبار" | awk "/ test | exam / (print $ 0)" $ echo "This is a exam" | awk "/ test | exam / (print $ 0)" $ echo "هذا شيء آخر" | awk "/ test | exam / (طباعة $ 0)"


منطقية أو في التعابير العادية

في هذا المثال ، تم تكوين التعبير العادي للبحث في النص عن الكلمات "اختبار" أو "اختبار". لاحظ أنه بين أجزاء القالب والرمز الفاصل | يجب ألا تكون هناك مسافات.

يمكن تجميع أجزاء التعبير العادي باستخدام الأقواس. إذا قمت بتجميع تسلسل معين من الشخصيات ، فسوف ينظر إليه النظام على أنه شخصية عادية. وهذا يعني ، على سبيل المثال ، أنه سيكون من الممكن تطبيق أحرف أولية مكررة عليه. هكذا تبدو:

صدى $ "أعجبني" | awk "/ Like (Geeks)؟ / (print $ 0)" $ echo "LikeGeeks" | awk "/ Like (Geeks)؟ / (print $ 0)"


تجميع أجزاء التعبير العادي

في هذه الأمثلة ، يتم وضع كلمة "Geeks" بين قوسين ، متبوعة بعلامة استفهام. تذكر أن علامة الاستفهام تعني "0 أو 1 تكرار" ، ونتيجة لذلك ، سوف يستجيب التعبير العادي للسلسلة "Like" والسلسلة "LikeGeeks".

أمثلة عملية

الآن بعد أن غطينا أساسيات التعبيرات النمطية ، حان الوقت لعمل شيء مفيد معهم.

عد عدد الملفات

دعنا نكتب سكربت bash يحسب الملفات في الدلائل المكتوبة إليها متغيرات البيئة مسار. للقيام بذلك ، ستحتاج أولاً إلى إنشاء قائمة من المسارات إلى الدلائل. لنفعل ذلك بـ sed ، ونستبدل النقطتين بمسافات:

$ صدى $ PATH | sed "s /: / / g"
يدعم أمر الاستبدال التعبيرات العادية كنماذج للبحث عن النص. في هذه الحالة ، كل شيء بسيط للغاية ، فنحن نبحث عن رمز النقطتين ، لكن لا أحد يكلف نفسه عناء استخدام شيء آخر هنا - كل هذا يتوقف على المهمة المحددة.
أنت الآن بحاجة إلى استعراض القائمة الناتجة في حلقة وتنفيذ الإجراءات اللازمة لحساب عدد الملفات هناك. سيكون المخطط العام للنص كما يلي:

Mypath \u003d $ (echo $ PATH | sed "s /: / / g") للدليل في $ mypath لم يتم
لنكتب الآن النص الكامل للنص ، باستخدام الأمر ls للحصول على معلومات حول عدد الملفات في كل مجلد:

#! / bin / bash mypath \u003d $ (echo $ PATH | sed "s /: / / g") count \u003d 0 للدليل في $ mypath do check \u003d $ (ls $ directory) للعنصر في $ check do count \u003d $ تم إجراء [$ count + 1] صدى "$ directory - $ count" count \u003d 0 تم
عند تشغيل البرنامج النصي ، قد يتضح أن بعض الأدلة من PATH غير موجودة ، ومع ذلك ، فإن هذا لا يمنعه من عد الملفات في الدلائل الموجودة.


عد الملفات

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

▍ التحقق من عناوين البريد الإلكتروني

هناك مواقع ويب بها مجموعات ضخمة من التعبيرات العادية التي تتيح لك التحقق من عناوين URL البريد الإلكترونيوأرقام الهواتف وما إلى ذلك. ومع ذلك ، من الجيد أن تأخذ شيئًا جاهزًا ، وأن تصنع شيئًا بنفسك شيء آخر. لذلك ، دعنا نكتب تعبيرًا عاديًا للتحقق من صحة عناوين البريد الإلكتروني. لنبدأ بتحليل البيانات الأولية. على سبيل المثال ، هنا عنوان معين:

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

مسلحين بهذه المعرفة ، فلنبدأ في تجميع التعبير النمطي من جانبه الأيسر ، والذي يعمل على التحقق من صحة اسم المستخدم. هذا ما حصلنا عليه:

^(+)@
يمكن قراءة هذا التعبير العادي على النحو التالي: "في بداية السطر ، يجب أن يكون هناك حرف واحد على الأقل من أولئك الموجودين في المجموعة المحددة بين قوسين مربعين ، متبوعًا بعلامة @."

الآن - قائمة انتظار اسم المضيف هي اسم المضيف. تنطبق نفس القواعد على اسم المستخدم ، لذا سيبدو القالب الخاص به كما يلي:

(+)
اسم النطاق افضل مستوى يخضع لقواعد خاصة. يمكن أن يكون هناك أحرف أبجدية فقط ، والتي يجب أن تكون على الأقل حرفين (على سبيل المثال ، تحتوي هذه المجالات عادةً على رمز البلد) ، وليس أكثر من خمسة. كل هذا يعني أن نموذج التحقق من الجزء الأخير من العنوان سيكون كالتالي:

\.({2,5})$
يمكنك قراءته على النحو التالي: "أولاً ، يجب أن تكون هناك فترة ، ثم - من 2 إلى 5 أحرف أبجدية ، وبعد ذلك ينتهي السطر".

بعد إعداد القوالب للأجزاء الفردية للتعبير النمطي ، دعنا نجمعها معًا:

^(+)@(+)\.({2,5})$
الآن يبقى فقط اختبار ما حدث:

صدى $ " [البريد الإلكتروني محمي]"| awk" / ^ (+)@(+)\\.((2،5))$/(print $ 0) "$ echo" [البريد الإلكتروني محمي]"| awk" / ^ (+)@(+)\\.((2،5))$/(print $ 0) "


التحقق من صحة عنوان البريد الإلكتروني باستخدام التعبيرات العادية

حقيقة أن النص الذي تم تمريره إلى awk معروض على الشاشة يعني أن النظام تعرف على عنوان البريد الإلكتروني الموجود فيه.

النتيجة

إذا بدا التعبير المعتاد للتحقق من صحة عناوين البريد الإلكتروني الذي قابلته في بداية المقالة غير مفهوم تمامًا ، فنحن نأمل ألا يبدو كمجموعة لا معنى لها من الأحرف. إذا كان هذا صحيحًا ، فإن هذه المادة قد حققت الغرض منها. في الواقع ، تعد التعبيرات العادية موضوعًا يمكن التعامل معه طوال حياتك ، ولكن حتى القليل الذي ناقشناه يمكن أن يساعدك بالفعل في كتابة نصوص تعالج النصوص بشكل متقدم جدًا.

في هذه السلسلة ، أظهرنا عادة جدًا أمثلة بسيطة نصوص bash التي كانت حرفياً عبارة عن بضعة أسطر. في المرة القادمة ، دعونا ننظر إلى شيء أكبر.

القراء الأعزاء! هل تستخدم التعبيرات العادية عند معالجة النص في البرامج النصية لسطر الأوامر؟

الوقت المناسب ، الضيوف!

في مقال اليوم أريد أن أتطرق إلى موضوع ضخم مثل التعبيرات العادية... أعتقد أن الجميع يعرف أن موضوع regexes (كما تسمى التعبيرات العادية بالعامية) هائل في حجم منشور واحد. لذلك ، سأحاول بإيجاز ، ولكن بشكل واضح قدر الإمكان ، جمع أفكاري معًا ونقلها إليك.

بادئ ذي بدء ، توجد عدة نكهات للتعبيرات النمطية:

1. التعبيرات النمطية التقليدية (كما أنها أساسية وأساسية و التعبيرات النمطية الأساسية (بري))

  • تم تعريف بناء جملة هذه التعبيرات على أنها قديمة ، ولكنها مع ذلك لا تزال منتشرة وتستخدم من قبل العديد من أدوات UNIX
  • تتضمن التعبيرات النمطية الأساسية الأحرف الأولية التالية (انظر أدناه للتعرف على معانيها):
    • \\ (\\) - أصلي لـ () (ممتد)
    • \\ (\\) - أصلي لـ () (ممتد)
    • \ن أين ن - رقم من 1 إلى 9
  • ميزات استخدام هذه الأحرف الأولية:
    • يجب أن تتبع العلامة النجمية تعبيرًا يطابق حرفًا واحدًا. مثال: *.
    • التعبير \\( منع\\) * يجب اعتباره غير صالح. في بعض الحالات ، تتطابق مع صفر أو أكثر من تكرار السلسلة منع ... في حالات أخرى ، يطابق السلسلة منع* .
    • داخل فئة الحرف ، يتم تجاهل معاني الأحرف الخاصة بشكل عام. حالات خاصة:
    • لإضافة حرف ^ إلى مجموعة ، يجب ألا يتم وضعه أولاً هناك.
    • لإضافة رمز - إلى مجموعة ، يجب وضعه هناك أولاً أو أخيرًا. فمثلا:
      • نمط اسم DNS ، والذي يمكن أن يتضمن أحرفًا وأرقامًا وناقصًا وفترات فاصلة: [-0-9a-zA-Z.] ؛
      • أي حرف ماعدا الطرح والرقم: [^ -0-9].
    • لإضافة الحرف [أو] إلى المجموعة ، يجب وضعه هناك أولاً. فمثلا:
      • يطابق] ، [، أ ، أو ب.

2. التعبيرات العادية الموسعة (هم انهم التعبيرات العادية الممتدة (ERE))

  • صيغة هذه التعبيرات هي نفسها المستخدمة في التعبيرات الرئيسية ، باستثناء:
    • تمت إزالة استخدام الخطوط المائلة العكسية للحروف الأولية () و ().
    • الشرطة المائلة للخلف أمام الحرف الأولي تلغي معناها الخاص.
    • رفض نظريا غير عادي اعمال بناء \\ ن .
    • تمت إضافة الأحرف الأولية + ،؟ ، | ...

3. التعبيرات العادية المتوافقة مع Perl(هم انهم التعبيرات العادية المتوافقة مع لغة Perl (PCRE))

  • لديها بناء جملة أكثر ثراءً ويمكن التنبؤ به في نفس الوقت من POSIX ERE ، لذلك غالبًا ما تستخدمه التطبيقات.

التعبيرات العادية يتألف منأو بالأحرى وضع نمط بحث. يتكون النموذج من قواعدعمليات البحث التي تتكون من الشخصياتو الحروف الأولية.

قواعد البحث المحددة من قبل ما يلي عمليات:

تعداد |

شريط عمودي (|) يفصل بين الخيارات المسموح بها ، يمكننا القول - منطقي OR. على سبيل المثال ، يطابق "الرمادي | الرمادي" اللون الرمادي أو اللون الرمادي.

التجمع أو الاتحاد ()

بين قوسين تستخدم لتحديد نطاق وأولوية المشغلين. على سبيل المثال ، "grey | grey" و "gr (a | e) y" نمطان مختلفان ، لكن كلاهما يصف مجموعة تحتوي على اللون الرمادي و اللون الرمادي.

تحديد الكميات ()؟ * +

محدد الكم بعد شخصية أو مجموعة تحدد عدد المرات قبليمكن أن يحدث التعبير.

التعبير العام ، يمكن أن يكون التكرار من m إلى n شاملة.

تعبير عام ، م أو أكثر من التكرار.

تعبير عام ، لا يزيد عن تكرار n.

ناعم ن التكرار.

علامة استفهاميعني 0 أو 1 مرات ، نفس {0,1} ... على سبيل المثال ، يطابق "colou؟ R" و اللونو اللون.

نجمةيعني 0 ، 1 أو أي رقم مرات ( {0,} ). على سبيل المثال ، يطابق "go * gle" ggle, غوغل, جوجل وإلخ.

زيادةيعني 1 على الأقل مرات ( {1,} ). على سبيل المثال ، يطابق "go + gle" غوغل, جوجل وهلم جرا (لكن ليس ggle).

يعتمد بناء الجملة المحدد لهذه التعبيرات العادية على التنفيذ. (أي في التعبيرات النمطية الأساسية حرف او رمز (و)- هرب بشرطة مائلة للخلف)

الحروف الأولية، بعبارات بسيطة ، هذه رموز لا تتوافق مع معناها الحقيقي ، أي رمز. (النقطة) ليست نقطة ، ولكن أي حرف واحد ، إلخ. يرجى التعرف على الحروف الأولية ومعانيها:

. يتوافق واحدأي شخصية
[شيئا ما] متوافق أي واحدحرف بين قوسين. في هذه الحالة: يتم تفسير الحرف "-" حرفيًا فقط إذا كان موجودًا بعد الفتح مباشرة أو قبل قوس الإغلاق: أو [-abc]. وإلا فإنه يشير إلى فاصل الأحرف. على سبيل المثال ، يطابق "أ" أو "ب" أو "ج". يتطابق مع الأحرف الصغيرة من الأبجدية اللاتينية. يمكن دمج هذه التعيينات: تطابق a ، b ، c ، q ، r ، s ، t ، u ، v ، w ، x ، y ، z. لمطابقة الأحرف "[" أو "]" ، يكفي أن يكون قوس الإغلاق كان الحرف الأول بعد الحرف الافتتاحي: يطابق "]" أو "[" أو "أ" أو "ب". إذا كانت القيمة الموجودة بين قوسين معقوفين مسبوقة بـ ^ ، فإن قيمة التعبير تطابق حرف واحد من بين هؤلاء التي ليست بين قوسين... على سبيل المثال ، يتطابق [^ abc] مع أي حرف بخلاف "a" أو "b" أو "c". يتطابق [^ a-z] مع أي حرف بخلاف الأحرف اللاتينية الصغيرة.
^ يطابق بداية النص (أو بداية أي سطر إذا كان وضع السطر).
$ يطابق نهاية النص (أو نهاية أي سطر إذا كان الوضع المضمّن).
\\ (\\) أو () يعلن عن "تعبير فرعي محدد" (تعبير مجمع) يمكن استخدامه لاحقًا (انظر العنصر التالي: \\ ن). "التعبير الفرعي المحدد" هو أيضًا "كتلة". على عكس عوامل التشغيل الأخرى ، هذا (في بناء الجملة التقليدي) يتطلب شرطة مائلة للخلف ، في الموسعة و Perl the \\ - ليست هناك حاجة.
\ن أين ن هو رقم من 1 إلى 9 ؛ يتوافق نالتعبير الفرعي الذي تم وضع علامة عليه (على سبيل المثال (abcd) \\ 0 ، أي ، يتم تمييز الأحرف abcd بصفر). هذا البناء من الناحية النظرية غير عادي، لم يتم قبوله في بناء جملة التعبير العادي الممتد.
*
  • نجمةبعد تطابق تعبير يطابق حرفًا واحدًا صفرأو أكثر نسخمن هذا التعبير (السابق). على سبيل المثال ، يطابق "*" سلسلة فارغة ، "x" ، "y" ، "zx" ، "zyx" ، إلخ.
  • \ن* أين ن هو رقم من 1 إلى 9 ، يتطابق مع صفر أو أكثر من التطابقات نالتعبير رقم عشر. على سبيل المثال ، "\\ (a. \\) C \\ 1 *" تطابق "abcab" و "abcaba" ولكن لا تطابق "abcac".

يجب اعتبار التعبير المضمن في "\\ (" و "\\)" متبوعًا بـ "*" غير صالح. في بعض الحالات ، تتطابق مع صفر أو أكثر من تكرارات السلسلة التي تم وضعها بين قوسين. في حالات أخرى ، يطابق التعبير المضمن بين قوسين ، بالنظر إلى الحرف "*".

\{x,ذ\} يطابق الأخير ( القادمة) لكتلة تحدث على الأقل x ولا اكثر ذ زمن. على سبيل المثال ، تطابق "a \\ (3،5 \\)" "aaa" أو "aaaa" أو "aaaaa". بخلاف عوامل التشغيل الأخرى ، يتطلب هذا (في النحو التقليدي) شرطة مائلة للخلف.
.* تعيين أي عدد من أي أحرف بين جزأين من التعبير العادي.

تساعدنا الأحرف الأولية على استخدام تطابقات مختلفة. ولكن كيف تمثل حرفًا أوليًا ذا حرف عادي ، أي الحرف [(قوس مربع) كقيمة قوس مربع؟ ببساطة:

  • يجب أن يسبق ( درع) الحرف الأولي (. * + \\؟ ()) الشرطة المائلة للخلف. فمثلا \\. أو \\ [

لتبسيط تعريف بعض مجموعات الأحرف ، تم دمجها في ما يسمى. فئات وفئات الشخصيات. قام POSIX بتوحيد الإعلان عن بعض فئات وفئات الرموز ، كما هو موضح في الجدول التالي:

فئة POSIX بالمثل تعيين
[: العلوي:] الأحرف الكبيرة
[: أقل:] أحرف صغيرة
[: alpha:] أحرف كبيرة وصغيرة
[: alnum:] الأرقام والأحرف الكبيرة والصغيرة
[: رقم:] الأرقام
[: xdigit:] أرقام سداسية عشرية
[: punct:] [.,!?:…] علامات الترقيم
[: فارغ:] [\\ t] الفضاء و TAB
[: الفراغ:] [\\ t \\ n \\ r \\ f \\ v] تخطي الأحرف
[: cntrl:] رموز التحكم
[: رسم بياني:] [^ \\ t \\ n \\ r \\ f \\ v] طباعة الرموز
[: طباعة:] [^ \\ t \\ n \\ r \\ f \\ v] طباعة وتخطي الأحرف

في regex يوجد شيء مثل:

جشع Regex

سأحاول وصفها بأكبر قدر ممكن من الوضوح. لنفترض أننا نريد إيجاد كل شيء علامات HTML في بعض النصوص. بعد ترجمة المهمة ، نريد العثور على القيم الموجودة بينهما< и >، جنبًا إلى جنب مع هذه الأقواس نفسها. لكننا نعلم أن هذه العلامات لها طول مختلف والعلامات نفسها ، ما لا يقل عن 50 قطعة.إدراجهم جميعًا في قائمة بالحروف الأولية مهمة تستغرق وقتًا طويلاً. لكننا نعلم أن لدينا تعبيرًا. * (نقطة النجمة) يميز أي عدد من أي حرف في السلسلة. باستخدام هذا التعبير ، سنحاول أن نجد في النص (

وبالتالي، كيفية إنشاء مستوى RAID 10/50 على وحدة تحكم LSI MegaRAID (صالح أيضًا لـ: Intel SRCU42x ، Intel SRCS16):

) كل القيم بين< и >... نتيجة لذلك ، ستطابق سلسلة ALL هذا التعبير. لماذا ، لأن التعبير العادي أخضر ويحاول التقاط أي عدد من الأحرف بينهما< и >، على التوالي ، السطر بأكمله يبدأ < p\u003e إذن ...وتنتهي ...> ستنتمي إلى هذه القاعدة!

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

  • تأخذ في الاعتبار الرموز ، ليس مطابقة النمط المطلوب (على سبيل المثال:<[^>] *\u003e للحالة أعلاه)
  • تخلص من الجشع بإضافة تعريف المُحدد الكمي بأنه غير جشع:
    • *؟ - ما يعادل "غير جشع" ("كسول") *
    • +؟ - ما يعادل "غير جشع" ("كسول") +
    • (ن،)؟ - "غير جشع" ("كسول") يعادل (n ،)
    • . *؟ - ما يعادل "غير جشع" ("كسول"). *

أريد أن أكمل كل ما سبق مع بناء جملة تعبير عادي ممتد:

التعبيرات العادية في POSIX تشبه صيغ يونكس التقليدية ، ولكن مع إضافة بعض الأحرف الأولية:

زيادةيدل علي السابقرمز أو مجموعةيمكن أن تتكرر مرة واحدة أو أكثر... على عكس علامة النجمة ، يلزم تكرار واحد على الأقل.

علامة استفهام هل السابقشخصية أو مجموعة اختيارية. بمعنى آخر ، في السطر المقابل لها قد يكون غائبًا أو موجودًا ناعم واحدزمن.

شريط عموديتشارك خيارات بديلة التعبيرات العادية. يحدد رمز واحد بديلين ، ولكن يمكن أن يكون هناك المزيد منها ، يكفي استخدام المزيد من الأشرطة الرأسية. تذكر أن هذا العامل يستخدم أكبر قدر ممكن من التعبير. لهذا السبب ، غالبًا ما يتم استخدام العامل البديل بين قوسين.

تم أيضًا إلغاء استخدام الخطوط المائلة العكسية: \\ (... \\) يصبح (...) و \\ (... \\) يصبح (...).

في نهاية المنشور ، إليك بعض الأمثلة على استخدام regex:

$ cat text1 1 تفاحة 2 كمثرى 3 موز $ grep p text1 1 تفاحة 2 كمثرى $ grep "pp *" text1 1 تفاحة 2 كمثرى $ قطة text1 | grep "l \\ | n" 1 تفاحة 3 موز $ echo -e "اعثر على \\ n * هنا" | grep "\\ *" * هنا $ grep "pl \\ ؟. * r" text1 # p على الأسطر التي بها r 2 كمثرى $ grep "a .." text1 # سطر متبوعًا بحرفين على الأقل 1 تفاحة 3 banana $ grep "" text1 # ابحث عن خطوط بها 3 أو p 1 apple 2 pear 3 banana $ echo -e "اعثر على \\ n * هنا \\ n في مكان آخر." | grep "[. *]" * هنا في مكان ما..name] $ echo -e "123 \\ n456 \\ n789 \\ n0" | grep "" 123456789 $ sed -e "/\\(a.*a\\)\\\\\\(p.*p\\)/s/a/A/g" text1 # استبدل a بـ A في كل السطور حيث بعد a يأتي a أو بعد p يأتي p 1 Apple 2 pear 3 bAnAnA * \\ ./ Last WORD./g "أولاً. كلمة أخيرة. هذه هي الكلمة الأخيرة.

مع خالص التقدير ، ماك سيم!

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

بادئ ذي بدء ، توجد عدة نكهات للتعبيرات النمطية:

1. التعبيرات النمطية التقليدية (كما أنها أساسية وأساسية و التعبيرات النمطية الأساسية (بري))

  • تم تعريف بناء جملة هذه التعبيرات على أنها قديمة ، ولكنها مع ذلك لا تزال منتشرة وتستخدم من قبل العديد من أدوات UNIX
  • تتضمن التعبيرات النمطية الأساسية الأحرف الأولية التالية (انظر أدناه للتعرف على معانيها):
    • \\ (\\) - أصلي لـ () (ممتد)
    • \\ (\\) - أصلي لـ () (ممتد)
    • \ن أين ن - رقم من 1 إلى 9
  • ميزات استخدام هذه الأحرف الأولية:
    • يجب أن تتبع العلامة النجمية تعبيرًا يطابق حرفًا واحدًا. مثال: *.
    • التعبير \\( منع\\) * يجب اعتباره غير صالح. في بعض الحالات ، تتطابق مع صفر أو أكثر من تكرار السلسلة منع ... في حالات أخرى ، يطابق السلسلة منع* .
    • داخل فئة الحرف ، يتم تجاهل معاني الأحرف الخاصة بشكل عام. حالات خاصة:
    • لإضافة حرف ^ إلى مجموعة ، يجب ألا يتم وضعه أولاً هناك.
    • لإضافة رمز - إلى مجموعة ، يجب وضعه هناك أولاً أو أخيرًا. فمثلا:
      • نمط اسم DNS ، والذي يمكن أن يتضمن أحرفًا وأرقامًا وناقصًا وفترات فاصلة: [-0-9a-zA-Z.] ؛
      • أي حرف ماعدا الطرح والرقم: [^ -0-9].
    • لإضافة الحرف [أو] إلى المجموعة ، يجب وضعه هناك أولاً. فمثلا:
      • يطابق] ، [، أ ، أو ب.

2. التعبيرات العادية الموسعة (هم انهم التعبيرات العادية الممتدة (ERE))

  • صيغة هذه التعبيرات هي نفسها المستخدمة في التعبيرات الرئيسية ، باستثناء:
    • تمت إزالة استخدام الخطوط المائلة العكسية للحروف الأولية () و ().
    • الشرطة المائلة للخلف أمام الحرف الأولي تلغي معناها الخاص.
    • رفض نظريا غير عادي اعمال بناء \\ ن .
    • تمت إضافة الأحرف الأولية + ،؟ ، | ...

3. التعبيرات العادية المتوافقة مع Perl(هم انهم التعبيرات العادية المتوافقة مع لغة Perl (PCRE))

  • لديها بناء جملة أكثر ثراءً ويمكن التنبؤ به في نفس الوقت من POSIX ERE ، لذلك غالبًا ما تستخدمه التطبيقات.

التعبيرات العادية يتألف منأو بالأحرى وضع نمط بحث. يتكون النموذج من قواعدعمليات البحث التي تتكون من الشخصياتو الحروف الأولية.

قواعد البحث المحددة من قبل ما يلي عمليات:

تعداد |

شريط عمودي (|) يفصل بين الخيارات المسموح بها ، يمكننا القول - منطقي OR. على سبيل المثال ، يطابق "الرمادي | الرمادي" اللون الرمادي أو اللون الرمادي.

التجمع أو الاتحاد ()

بين قوسين تستخدم لتحديد نطاق وأولوية المشغلين. على سبيل المثال ، "grey | grey" و "gr (a | e) y" نمطان مختلفان ، لكن كلاهما يصف مجموعة تحتوي على اللون الرمادي و اللون الرمادي.

تحديد الكميات ()؟ * +

محدد الكم بعد شخصية أو مجموعة تحدد عدد المرات قبليمكن أن يحدث التعبير.

التعبير العام ، يمكن أن يكون التكرار من m إلى n شاملة.

تعبير عام ، م أو أكثر من التكرار.

تعبير عام ، لا يزيد عن تكرار n.

ناعم ن التكرار.

علامة استفهاميعني 0 أو 1 مرات ، نفس {0,1} ... على سبيل المثال ، يطابق "colou؟ R" و اللونو اللون.

نجمةيعني 0 ، 1 أو أي رقم مرات ( {0,} ). على سبيل المثال ، يطابق "go * gle" ggle, غوغل, جوجل وإلخ.

زيادةيعني 1 على الأقل مرات ( {1,} ). على سبيل المثال ، يطابق "go + gle" غوغل, جوجل وهلم جرا (لكن ليس ggle).

يعتمد بناء الجملة المحدد لهذه التعبيرات العادية على التنفيذ. (أي في التعبيرات النمطية الأساسية حرف او رمز (و)- هرب بشرطة مائلة للخلف)

الحروف الأولية، بعبارات بسيطة ، هذه رموز لا تتوافق مع معناها الحقيقي ، أي رمز. (النقطة) ليست نقطة ، ولكن أي حرف واحد ، إلخ. يرجى التعرف على الحروف الأولية ومعانيها:

. يتوافق واحدأي شخصية
[شيئا ما] متوافق أي واحدحرف بين قوسين. في هذه الحالة: يتم تفسير الحرف "-" حرفيًا فقط إذا كان موجودًا بعد الفتح مباشرة أو قبل قوس الإغلاق: أو [-abc]. وإلا فإنه يشير إلى فاصل الأحرف. على سبيل المثال ، يطابق "أ" أو "ب" أو "ج". يتطابق مع الأحرف الصغيرة من الأبجدية اللاتينية. يمكن دمج هذه التعيينات: تطابق a ، b ، c ، q ، r ، s ، t ، u ، v ، w ، x ، y ، z. لمطابقة الأحرف "[" أو "]" ، يكفي أن يكون قوس الإغلاق كان الحرف الأول بعد الحرف الافتتاحي: يطابق "]" أو "[" أو "أ" أو "ب". إذا كانت القيمة الموجودة بين قوسين معقوفين مسبوقة بـ ^ ، فإن قيمة التعبير تطابق حرف واحد من بين هؤلاء التي ليست بين قوسين... على سبيل المثال ، يتطابق [^ abc] مع أي حرف بخلاف "a" أو "b" أو "c". يتطابق [^ a-z] مع أي حرف بخلاف الأحرف اللاتينية الصغيرة.
^ يطابق بداية النص (أو بداية أي سطر إذا كان وضع السطر).
$ يطابق نهاية النص (أو نهاية أي سطر إذا كان الوضع المضمّن).
\\ (\\) أو () يعلن عن "تعبير فرعي محدد" (تعبير مجمع) يمكن استخدامه لاحقًا (انظر العنصر التالي: \\ ن). "التعبير الفرعي المحدد" هو أيضًا "كتلة". على عكس عوامل التشغيل الأخرى ، هذا (في بناء الجملة التقليدي) يتطلب شرطة مائلة للخلف ، في الموسعة و Perl the \\ - ليست هناك حاجة.
\ن أين ن - هذا رقم من 1 إلى 9 ؛ يتوافق نالتعبير الفرعي الذي تم وضع علامة عليه (على سبيل المثال (abcd) \\ 0 ، أي ، يتم تمييز الأحرف abcd بصفر). هذا البناء من الناحية النظرية غير عادي، لم يتم قبوله في بناء جملة التعبير العادي الممتد.
*
  • نجمةبعد تطابق تعبير يطابق حرفًا واحدًا صفرأو أكثر نسخمن هذا التعبير (السابق). على سبيل المثال ، يطابق "*" سلسلة فارغة ، "x" ، "y" ، "zx" ، "zyx" ، إلخ.
  • \ن* أين ن هو رقم من 1 إلى 9 ، يتطابق مع صفر أو أكثر من التكرارات للمطابقة نالتعبير رقم عشر. على سبيل المثال ، "\\ (a. \\) C \\ 1 *" تطابق "abcab" و "abcaba" ولكن لا تطابق "abcac".

يجب اعتبار التعبير المضمن في "\\ (" و "\\)" متبوعًا بـ "*" غير صالح. في بعض الحالات ، تتطابق مع صفر أو أكثر من تكرارات السلسلة التي تم وضعها بين قوسين. في حالات أخرى ، يطابق التعبير المضمن بين قوسين ، بالنظر إلى الحرف "*".

\{x,ذ\} يطابق الأخير ( القادمة) لكتلة تحدث على الأقل x ولا اكثر ذ زمن. على سبيل المثال ، تطابق "a \\ (3،5 \\)" "aaa" أو "aaaa" أو "aaaaa". بخلاف عوامل التشغيل الأخرى ، يتطلب هذا (في النحو التقليدي) شرطة مائلة للخلف.
.* تعيين أي عدد من أي أحرف بين جزأين من التعبير العادي.

تساعدنا الأحرف الأولية على استخدام تطابقات مختلفة. ولكن كيف تمثل حرفًا أوليًا ذا حرف عادي ، أي الحرف [(قوس مربع) كقيمة قوس مربع؟ ببساطة:

  • يجب أن يسبق ( درع) الحرف الأولي (. * + \\؟ ()) الشرطة المائلة للخلف. فمثلا \\. أو \\ [

لتبسيط تعريف بعض مجموعات الأحرف ، تم دمجها في ما يسمى. فئات وفئات الشخصيات. قام POSIX بتوحيد الإعلان عن بعض فئات وفئات الرموز ، كما هو موضح في الجدول التالي:

فئة POSIX بالمثل تعيين
[: العلوي:] الأحرف الكبيرة
[: أقل:] أحرف صغيرة
[: alpha:] أحرف كبيرة وصغيرة
[: alnum:] الأرقام والأحرف الكبيرة والصغيرة
[: رقم:] الأرقام
[: xdigit:] أرقام سداسية عشرية
[: punct:] [.,!?:…] علامات الترقيم
[: فارغ:] [\\ t] الفضاء و TAB
[: الفراغ:] [\\ t \\ n \\ r \\ f \\ v] تخطي الأحرف
[: cntrl:] رموز التحكم
[: رسم بياني:] [^ \\ t \\ n \\ r \\ f \\ v] طباعة الرموز
[: طباعة:] [^ \\ t \\ n \\ r \\ f \\ v] طباعة وتخطي الأحرف

في regex يوجد شيء مثل:

جشع Regex

سأحاول وصفها بأكبر قدر ممكن من الوضوح. لنفترض أننا نريد العثور على جميع علامات HTML في بعض النصوص. بعد ترجمة المهمة ، نريد العثور على القيم الموجودة بينهما< и >، جنبًا إلى جنب مع هذه الأقواس نفسها. لكننا نعلم أن العلامات لها أطوال مختلفة وأن العلامات نفسها ، على الأقل 50 قطعة.لإدراجهم جميعًا ، يعد إرفاقهم بأحرف أولية مهمة تستغرق وقتًا طويلاً. لكننا نعلم أن لدينا تعبيرًا. * (نقطة النجمة) يميز أي عدد من أي حرف في السلسلة. باستخدام هذا التعبير ، سنحاول أن نجد في النص (

وبالتالي، كيفية إنشاء مستوى RAID 10/50 على وحدة تحكم LSI MegaRAID (صالح أيضًا لـ: Intel SRCU42x ، Intel SRCS16):

) كل القيم بين< и >... نتيجة لذلك ، ستطابق سلسلة ALL هذا التعبير. لماذا ، لأن التعبير العادي أخضر ويحاول التقاط أي عدد من الأحرف بينهما< и >، على التوالي ، السطر بأكمله يبدأ < p\u003e إذن ...وتنتهي ...> ستنتمي إلى هذه القاعدة!

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

  • تأخذ في الاعتبار الرموز ، ليس مطابقة النمط المطلوب (على سبيل المثال:<[^>] *\u003e للحالة أعلاه)
  • تخلص من الجشع بإضافة تعريف المُحدد الكمي بأنه غير جشع:
    • *؟ - ما يعادل "غير جشع" ("كسول") *
    • +؟ - ما يعادل "غير جشع" ("كسول") +
    • (ن،)؟ - "غير جشع" ("كسول") يعادل (n ،)
    • . *؟ - ما يعادل "غير جشع" ("كسول"). *

أريد أن أكمل كل ما سبق مع بناء جملة تعبير عادي ممتد:

التعبيرات العادية في POSIX تشبه صيغ يونكس التقليدية ، ولكن مع إضافة بعض الأحرف الأولية:

زيادةيدل علي السابقرمز أو مجموعةيمكن أن تتكرر مرة واحدة أو أكثر... على عكس علامة النجمة ، يلزم تكرار واحد على الأقل.

علامة استفهام هل السابقشخصية أو مجموعة اختيارية. بمعنى آخر ، في السطر المقابل لها قد يكون غائبًا أو موجودًا ناعم واحدزمن.

شريط عمودييفصل بين التعبيرات النمطية البديلة. يحدد رمز واحد بديلين ، ولكن يمكن أن يكون هناك المزيد منها ، يكفي استخدام المزيد من الأشرطة الرأسية. تذكر أن هذا العامل يستخدم أكبر قدر ممكن من التعبير. لهذا السبب ، غالبًا ما يتم استخدام العامل البديل بين قوسين.

تم أيضًا إلغاء استخدام الخطوط المائلة العكسية: \\ (... \\) يصبح (...) و \\ (... \\) يصبح (...).

في نهاية المنشور ، إليك بعض الأمثلة على استخدام regex:

$ cat text1 1 apple 2 pear 3 banana $ grep p text1 1 apple 2 pear $ grep pea text1 2 pear $ grep "p *" text1 1 apple 2 pear 3 banana $ grep "pp *" text1 1 apple 2 pear $ grep " x "text1 $ grep" x * "text1 1 apple 2 pear 3 banana $ cat text1 | grep "l \\ | n" 1 تفاحة 3 موز $ echo -e "اعثر على \\ n * هنا" | grep "\\ *" * هنا $ grep "pp \\ +" text1 # سطر يحتوي على p و 1 أو أكثر p 1 apple $ grep "pl \\؟ e" text1 1 apple 2 pear $ grep "pl \\؟ e" text1 # pe مع الحرف المحتمل l 1 apple 2 pear $ grep "p. * r" text1 # p ، في أسطر تحتوي على r 2 pear $ grep "a .." text1 # سطور متبوعة بحرفين على الأقل 1 apple 3 banana $ grep "\\ (an \\) \\ +" text1 # ابحث عن المزيد من التكرارات an 3 banana $ grep "an \\ (an \\) \\ +" text1 # ابحث عن مكررين و 3 موز $ grep "" text1 # بحث سطور بها 3 أو p 1 apple 2 pear 3 banana $ echo -e "اعثر على \\ n * هنا \\ n في مكان آخر." | grep "[. *]" * هنا في مكان ما. $ # للبحث عن الأحرف من 3 إلى 7 $ echo -e "123 \\ n456 \\ n789 \\ n0" | grep "" 123 456 789 $ # البحث عن رقم بدون أحرف n و r حتى نهاية السطر $ grep "[[: digit:]] [^ nr] * $" text1 1 apple $ sed -e "/ \\ (a . * a \\) \\ | \\ (p. * p \\) / s / a / A / g "text1 # استبدل a بـ A في جميع الأسطر حيث يأتي a بعد a أو p بعد p 1 Apple 2 pear 3 bAnAnA $ sed -e "/ ^ [^ lmnXYZ] * $ / s / ear / each / g" text1 # استبدل الأذن مع كل سطر في سطر لا يبدأ بـ lmnXYZ 1 apple 2 peach 3 banana $ echo "أولاً. عبارة. هذه هي جملة. " | \\ # استبدل الكلمة الأخيرة في الجملة بـ LAST WORLD. \u003e sed -e "s / [^] * \\ ./ LAST WORD./g" أولاً. كلمة أخيرة. هذه كلمة أخيرة.

تعد التعبيرات العادية أداة قوية جدًا لمطابقة النمط ومعالجة وتعديل السلاسل التي يمكن استخدامها في مجموعة متنوعة من المهام. فيما يلي أهمها:

  • فحص إدخال النص ؛
  • البحث عن نص واستبداله في ملف ؛
  • إعادة تسمية دفعة من الملفات ؛
  • التفاعل مع خدمات مثل Apache ؛
  • التحقق من السلسلة مقابل النمط.

هذا بعيد عن القائمة الكاملة، هناك الكثير مما يمكنك فعله باستخدام التعبيرات العادية. ولكن بالنسبة للمستخدمين الجدد ، قد تبدو معقدة للغاية ، حيث يتم استخدام لغة خاصة لتكوينهم. ولكن نظرًا للإمكانيات المتوفرة ، يجب أن تكون تعبيرات Linux العادية معروفة ويستخدمها الجميع. مدير النظام.

في هذه المقالة ، سنرشدك خلال تعبيرات bash العادية للمبتدئين حتى تتمكن من فهم جميع ميزات هذه الأداة.

هناك نوعان من الأحرف التي يمكن استخدامها في التعبيرات العادية:

  • رسائل عادية
  • الحروف الأولية.

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

الحروف الأولية هي شيء آخر ، فهي التي تعطي القوة للتعبيرات النمطية. باستخدام الأحرف الأولية ، يمكنك القيام بأكثر من مجرد البحث عن حرف واحد. يمكنك البحث عن مجموعات من الأحرف ، واستخدام عدد ديناميكي من الأحرف ، واختيار نطاقات. يمكن تقسيم جميع الأحرف الخاصة إلى نوعين ، وهما الأحرف البديلة ، التي تحل محل الأحرف العادية ، أو عوامل التشغيل التي تشير إلى عدد المرات التي يمكن فيها تكرار الحرف. سيبدو بناء جملة التعبير العادي كما يلي:

عادي_حرف مشغل_حرف خاص

حرف خاص مشغل_حرف خاص

  • - تبدأ الأحرف الخاصة الحرفية بشرطة مائلة للخلف ، وتُستخدم أيضًا إذا كنت بحاجة إلى استخدام حرف خاص في شكل علامة ترقيم ؛
  • ^ - يشير إلى بداية السطر ؛
  • $ - يشير إلى نهاية السطر ؛
  • * - يشير إلى أنه يمكن تكرار الحرف السابق 0 أو أكثر ؛
  • + - يشير إلى ضرورة تكرار الحرف السابق أكثر من مرة أو أكثر ؛
  • ? - يمكن أن تحدث الشخصية السابقة صفر أو مرة واحدة ؛
  • (ن) - يشير إلى عدد المرات (ن) لتكرار الحرف السابق ؛
  • (ن ، ن) - يمكن تكرار الحرف السابق من N إلى n مرة ؛
  • . - أي حرف باستثناء خط التغذية ؛
  • - أي حرف محدد بين قوسين ؛
  • س | ص - الرمز x أو الرمز y ؛
  • [^ az] - أي شخصية غير تلك المشار إليها بين قوسين ؛
  • - أي حرف من النطاق المحدد ؛
  • [^ a-z] - أي حرف غير موجود في النطاق ؛
  • ب - تشير إلى حد الكلمة بمسافة ؛
  • ب - يعني أن الحرف يجب أن يكون داخل كلمة ، على سبيل المثال ، ux يطابق uxb أو tuxedo ، لكنه لا يتطابق مع Linux ؛
  • د - يعني أن الرمز هو رقم ؛
  • د - شخصية غير رقمية ؛
  • ن - حرف تغذية الخط ؛
  • س - مسافة أحد الأحرف والمسافة وعلامة التبويب وما إلى ذلك ؛
  • س - أي حرف ما عدا مسافة ؛
  • ر - طابع الجدولة ؛
  • الخامس - حرف جدولة عمودي ؛
  • ث - أي حرف أبجدي ، بما في ذلك الشرطة السفلية ؛
  • دبليو - أي حرف أبجدي باستثناء الشرطة السفلية ؛
  • uXXX - رمز Unicdoe.

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

على سبيل المثال ، تريد البحث عن السلسلة 1+ 2 \u003d 3 في النص. إذا استخدمت هذه السلسلة كتعبير عادي فلن تجد شيئًا ، لأن النظام يفسر علامة الجمع على أنها حرف خاص ، والذي ينص على أن الوحدة السابقة يجب أن تتكرر مرة أو أكثر. لذلك يجب أن يتم تخطيها: 1 + 2 \u003d 3. بدون هروب ، فإن التعبير العادي الخاص بنا سيتطابق فقط مع السلسلة 11 \u003d 3 أو 111 \u003d 3 ، وهكذا. لا تحتاج إلى وضع سطر قبل يساوي ، لأنه ليس حرفًا خاصًا.

أمثلة على استخدام التعبيرات النمطية

الآن بعد أن غطينا الأساسيات وأنت تعرف كيف يعمل كل شيء ، يبقى تعزيز المعرفة المكتسبة حول التعبيرات العادية لـ linux grep في الممارسة العملية. رمزان خاصان مفيدان للغاية هما ^ و $ ، ويشيران إلى بداية السطر ونهايته. على سبيل المثال ، نريد تسجيل جميع المستخدمين في نظامنا الذين يبدأ اسمهم بحرف s. ثم يمكن تطبيق التعبير النمطي "^ S"... يمكنك استخدام الأمر egrep:

egrep "^ s" / etc / passwd

إذا أردنا تحديد الأسطر حسب الحرف الأخير في السطر ، فيمكننا استخدام $ لهذا الغرض. على سبيل المثال ، دعنا نختار الكل مستخدمي النظام، بدون shell ، تنتهي إدخالات هؤلاء المستخدمين بالخطأ:

egrep "false $" / etc / passwd

لعرض أسماء المستخدمين التي تبدأ بحرف s أو d ، استخدم تعبيرًا مثل هذا:

egrep "^" / etc / passwd

يمكن الحصول على نفس النتيجة باستخدام الحرف "|". يكون الخيار الأول أكثر ملاءمة للنطاقات ، ويتم استخدام الخيار الثاني في الغالب في الوضع العادي و / أو:

egrep "^" / etc / passwd

لنحدد الآن جميع المستخدمين الذين يزيد أسماؤهم عن ثلاثة أحرف. ينتهي اسم المستخدم بنقطتين. يمكننا القول أنه يمكن أن يحتوي على أي حرف أبجدي يجب تكراره ثلاث مرات قبل النقطتين:

egrep "^ w (3):" / etc / passwd

الاستنتاجات

لقد قمنا بتغطية تعبيرات Linux العادية في هذه المقالة ، لكن تلك كانت مجرد الأساسيات. إذا تعمقت قليلاً ، ستجد أن هناك الكثير من الأشياء المثيرة للاهتمام التي يمكنك القيام بها باستخدام هذه الأداة. الوقت المستغرق في تعلم التعبيرات العادية سيكون بالتأكيد يستحق العناء.

في نهاية محاضرة Yandex حول التعبيرات النمطية: