JavaRush /مدونة جافا /Random-AR /RegEx: 20 خطوة قصيرة لإتقان التعبيرات العادية الجزء 2
Artur
مستوى
Tallinn

RegEx: 20 خطوة قصيرة لإتقان التعبيرات العادية الجزء 2

نشرت في المجموعة
RegEx: 20 خطوة قصيرة لإتقان التعبيرات العادية الجزء 1 الأصلي هنا في الجزء الأخير، أتقننا أبسط التعبيرات النمطية، وتعلمنا شيئًا ما بالفعل. في هذا الجزء سوف ندرس تصميمات أكثر تعقيدًا بعض الشيء، لكن صدقوني، لن يكون الأمر صعبًا كما قد يبدو. RegEx: 20 خطوة قصيرة لإتقان التعبيرات العادية  الجزء 2 - 1لذلك دعونا نستمر!

الخطوة 8: *علامة النجمة وعلامة الزائد+

RegEx: 20 خطوة قصيرة لإتقان التعبيرات العادية  الجزء 2 - 2حتى الآن، تمكنا بشكل أو بآخر من مطابقة سلاسل ذات طول معين فقط. لكن في المشاكل الأخيرة اقتربنا من الحد الأقصى لما يمكننا فعله بالتدوين الذي رأيناه حتى الآن. لنفترض، على سبيل المثال، أننا لا نقتصر على معرفات Java المكونة من 3 أحرف، ولكن يمكننا الحصول على معرفات بأي طول. الحل الذي ربما نجح في المثال السابق لن يعمل في المثال التالي:
النمط: [a-zA-Z_$]\w\w 
السلسلة:   __e $12 3 3.2 fo Bar r a23 mm ab x
التطابقات: ^^^ ^^^ ^^^ ^^^  
( مثال ) ملحوظةأنه عندما يكون المعرف صالحًا ولكن أطول من 3 أحرف، تتم مطابقة الأحرف الثلاثة الأولى فقط. وعندما يكون المعرف صالحًا ولكنه يحتوي على أقل من 3 أحرف، فلن يجده regex على الإطلاق! تكمن المشكلة في أن التعبيرات الموجودة بين قوسين []تتطابق مع حرف واحد تمامًا، كما هو الحال مع فئات الأحرف مثل \w. وهذا يعني أن أي تطابقات في التعبير العادي أعلاه يجب أن تتكون من ثلاثة أحرف بالضبط. لذا فإن الأمر لا يعمل كما كنا نأمل. *الشخصيات الخاصة ويمكن أن تساعد هنا +. هذه هي المعدلات التي يمكن إضافتها إلى يمين أي تعبير لمطابقة هذا التعبير أكثر من مرة. *ستشير نجمة كلين (أو "العلامة النجمية") إلى أنه يجب مطابقة الرمز المميز السابق لأي عدد من المرات، بما في ذلك صفر مرة. +ستشير علامة الزائد إلى أنك بحاجة إلى البحث مرة واحدة أو أكثر. وبالتالي فإن التعبير الذي يسبقه +يكون إلزاميا (مرة واحدة على الأقل)، في حين أن التعبير الذي يسبقه *يكون اختياريا، ولكن عند ظهوره يمكن أن يظهر أي عدد من المرات. الآن، مع هذه المعرفة، يمكننا تصحيح التعبير العادي أعلاه:
النمط: [a-zA-Z_$]\w* 
السلسلة:   __e $123 3.2 for Barr a23mm ab x 
match: ^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^ ^ 
( مثال ) الآن نقوم بمطابقة المعرفات الصالحة بأي طول! البنغو! ولكن ماذا سيحدث لو استخدمنا ? +بدلاً من *?
النمط: [a-zA-Z_$]\w+ 
السلسلة:   __e $123 3.2 fo Barr a23mm ab x
التطابقات: ^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^ 
( مثال ) فاتتنا المباراة الأخيرة، х. وذلك لأنه يتطلب +مطابقة حرف واحد على الأقل، ولكن نظرًا لأن التعبير الموجود بين قوسين []السابق \w+قد "أكل" الحرف بالفعل x، فلا يوجد المزيد من الأحرف المتاحة، لذا تفشل المطابقة. متى يمكننا استخدامها +؟ عندما نحتاج إلى العثور على تطابق واحد على الأقل، ولكن لا يهم عدد المرات التي يجب أن يتطابق فيها تعبير معين. على سبيل المثال، إذا أردنا العثور على أي أرقام تحتوي على علامة عشرية:
النمط: \d*\.\d+ 
السلسلة:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 
التطابقات: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^  
( مثال ) ملحوظةأنه من خلال جعل الأرقام الموجودة على يسار العلامة العشرية اختيارية، تمكنا من العثور على كل من 0.011 و.2. للقيام بذلك، كنا بحاجة إلى مطابقة علامة عشرية واحدة بالضبط مع \.رقم واحد على الأقل على يمين العلامة العشرية \d+. لن يتطابق التعبير العادي أعلاه مع رقم مثل 3.، لأننا نحتاج إلى رقم واحد على الأقل على يمين العلامة العشرية للمطابقة.

كالعادة، دعونا نحل بعض المشاكل البسيطة:

ابحث عن جميع الكلمات الإنجليزية في المقطع أدناه.
نمط:
السلسلة: 3 زائد 3 يساوي ستة لكن 4 زائد ثلاثة يساوي 7
التطابقات:    ^^^^ ^^ ^^^ ^^^ ^^^^ ^^^^^ ^^ 
( الحل ) ابحث عن جميع رموز حجم الملف في القائمة أدناه. ستتكون أحجام الملفات من رقم (مع أو بدون علامة عشرية) متبوعًا KBبـ MBأو GBأو TB:
نمط:
السلسلة:   11 تيرابايت 13 14.4 ميجابايت 22HB 9.9 جيجابايت تيرابايت 0 كيلو بايت 
التطابقات: ^^^^ ^^^^^^ ^^^^^ ^^^  
( حل )

الخطوة 9: علامة استفهام "اختيارية".?

RegEx: 20 خطوة قصيرة لإتقان التعبيرات العادية  الجزء 2 - 3هل كتبت بالفعل regex لحل المشكلة الأخيرة؟ هل نجحت؟ والآن حاول تطبيقه هنا:
نمط:
السلسلة: 1..3 كيلو بايت 5... جيجا بايت ..6 تيرابايت
اعواد الكبريت:  
من الواضح أن أيًا من هذه التعيينات لا يمثل حجم ملف صالحًا، لذا يجب ألا يتطابق التعبير العادي الجيد مع أي منهما. الحل الذي كتبته لحل المشكلة الأخيرة يتطابق معها جميعًا، جزئيًا على الأقل:
النمط: \d+\.*\d*[KMGT] 
سلسلة B:   1..3 كيلو بايت  5... جيجا بايت .. 6 تيرابايت 
مطابق: ^^^^^^ ^^^^^^ ^^^ 
( مثال ) إذن ما هي المشكلة؟ في الواقع، علينا فقط إيجاد علامة عشرية واحدة، إذا كانت هناك واحدة. ولكنه *يسمح بأي عدد من التطابقات، بما في ذلك الصفر. هل هناك طريقة لمطابقة صفر مرة فقط أو مرة واحدة؟ ولكن ليس أكثر من مرة؟ بالطبع. "اختياري" ?هو مُعدِّل يطابق الصفر أو أحد الأحرف السابقة، ولكن ليس أكثر:
النمط: \d+\.?\d*[KMGT] 
سلسلة B: 1..3 كيلو بايت 5...جيجابايت .. 6 تيرابايت 
مطابق:     ^^^ ^^^ 
( مثال ) نحن أقرب إلى الحل هنا، ولكن هذا ليس ما نحتاجه تمامًا. سنرى كيفية إصلاح ذلك في بضع خطوات بعد قليل.

في غضون ذلك، دعونا نحل هذه المشكلة:

في بعض لغات البرمجة (مثل Java)، قد تكون بعض الأرقام الصحيحة والفاصلة العائمة (النقطة) متبوعة بـ l/ Lو f/ Fللإشارة إلى أنه يجب معاملتها على أنها طويلة/عائمة (على التوالي) بدلاً من التعامل معها على أنها int/double عادية. ابحث عن جميع الأرقام "الطويلة" الصالحة في السطر أدناه:
نمط:
سلسلة:   13L طويلة 2L 19 L LL 0 
مباريات: ^^^ ^^ ^^ ^ 
( حل )

الخطوة 10: علامة "أو"|

RegEx: 20 خطوة قصيرة لإتقان التعبيرات العادية  الجزء 2 - 4في الخطوة 8، واجهنا بعض الصعوبة في العثور على الأنواع المختلفة لأرقام الفاصلة العائمة:
النمط: \d*\.\d+ 
السلسلة:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 
التطابقات: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^  
يتطابق النمط أعلاه مع الأرقام ذات الفاصلة العشرية ورقم واحد على الأقل على يمين العلامة العشرية. ولكن ماذا لو أردنا أيضًا مطابقة سلاسل مثل 0.؟ (لا توجد أرقام على يمين العلامة العشرية.) يمكننا كتابة تعبير عادي مثل هذا:
النمط: \d*\.\d* 
السلسلة:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. . 
التطابقات: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ ^ 
( مثال ) هذا يتطابق 0.، ولكنه يطابق أيضًا نقطة واحدة .، كما ترون أعلاه. في الواقع ما نحاول مطابقته هو فئتان مختلفتان من السلاسل:
  1. أرقام تحتوي على رقم واحد على الأقل على يمين العلامة العشرية
  2. أرقام تحتوي على رقم واحد على الأقل على يسار العلامة العشرية
لنكتب التعبيرين العاديين التاليين، بشكل مستقل عن بعضهما البعض:
النمط: \d*\.\d+ 
السلسلة:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. .
التطابقات: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^  
النمط: \d+\.\d* 
السلسلة:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. .
التطابقات: ^^^^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ 
نرى أنه في أي من هذه الحالات لم يتم العثور على السلاسل الفرعية أو أو 42بواسطة 5المحرك . وللحصول على النتيجة المطلوبة، لن يضرنا الجمع بين هذه التعبيرات النمطية. كيف نستطيع إنجاز هذا؟ تتيح لنا علامة "أو" تحديد عدة تسلسلات محتملة للتطابقات مرة واحدة في التعبير العادي. مثلما تسمح لنا علامة "أو" بتحديد أحرف مفردة بديلة، يمكننا تحديد تعبيرات بديلة متعددة الأحرف. على سبيل المثال، إذا أردنا العثور على كلمة "كلب" أو "قطة"، يمكننا كتابة شيء مثل هذا: 6.|[]|
النمط: \w\w\w 
السلسلة:   من الواضح أن الكلب حيوان أليف أفضل من القطة .
التطابقات: ^^^^^^^^^ ^^^ ^^^^^^ ^^^ ^^^ ^^^ 
( مثال )... ولكن هذا يطابق جميع تسلسلات الأحرف الثلاثية للفئة "كلمة". لكن "كلب" و"قطة" ليس لديهما أحرف مشتركة، لذا فإن الأقواس المربعة لن تساعدنا هنا. إليك أبسط تعبير عادي يمكننا استخدامه والذي يتطابق مع هاتين الكلمتين فقط:
النمط: كلب | 
سلسلة قطة: من الواضح أن الكلب حيوان أليف أفضل من القطة .
التطابقات:               ^^^ ^^^ 
( مثال ) يحاول محرك التعبير العادي أولاً مطابقة التسلسل بأكمله على يسار الحرف |، ولكن إذا فشل، فإنه يحاول بعد ذلك مطابقة التسلسل على يمين الحرف |. يمكن أيضًا ربط عدة أحرف |لمطابقة أكثر من تسلسلين بديلين:
النمط: كلب|قط| 
سلسلة حيوانات أليفة: من الواضح أن الكلب حيوان أليف أفضل من القطة .
التطابقات:               ^^^ ^^^ ^^^ 
( مثال )

الآن دعونا نحل مشكلتين أخريين لفهم هذه الخطوة بشكل أفضل:

استخدم العلامة |لتصحيح التعبير العادي العشري أعلاه لإنتاج نتيجة مثل هذا:
نمط:
السلسلة:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. .
التطابقات: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^^^ 
( الحل ) استخدم العلامات |وفئات الأحرف و"اختياري" ?وما إلى ذلك لإنشاء تعبير عادي واحد يتطابق مع كل من الأعداد الصحيحة والأرقام الفاصلة العائمة (النقطة)، كما تمت مناقشته في المشكلة في نهاية الخطوة السابقة (هذه المشكلة قليلاً أكثر تعقيدا، نعم ;))
نمط:
السلسلة:   42L 12 x 3.4f 6l 3.3 0F LF .2F 0. 
المباريات: ^^^ ^^ ^^^^ ^^ ^^^ ^^ ^^^ ^^  
( الحل ) 20 خطوة قصيرة لإتقان التعبيرات العادية. الجزء 3 RegEx: 20 خطوة قصيرة لإتقان التعبيرات العادية. الجزء 4
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION