regex - ماهو الفرق بين.*؟ و*التعبيرات العادية؟




regex-greedy (2)

أحاول تقسيم سلسلة إلى جزئين باستخدام regex. يتم تنسيق السلسلة كما يلي:

text to extract<number>

لقد تم استخدام (.*?)< و <(.*?)> التي تعمل بشكل جيد ولكن بعد قراءة regex قليلا ، لقد بدأت للتو أتساءل لماذا أنا في حاجة ? في التعبيرات. لقد فعلت ذلك فقط بعد العثور عليها من خلال هذا الموقع لذلك أنا لست متأكدة بالضبط ما هو الفرق.


على الجشع مقابل غير الجشع

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

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

المراجع

المثال 1: من الألف إلى الياء

دعونا نقارن بين هذين النمطين: A.*Z و A.*?Z

بالنظر إلى المدخلات التالية:

eeeAiiZuuuuAoooZeeee

تعطي الأنماط التطابقات التالية:

دعونا نركز أولا على ما يفعله A.*Z . عندما يتطابق مع A ، الأول ، .* ، يجري الجشع ، لأول مرة لتتناسب مع أكبر عدد ممكن . بقدر الإمكان.

eeeAiiZuuuuAoooZeeee
   \_______________/
    A.* matched, Z can't match

بما أن Z غير متطابق ، فإن المحرك الخلفى و .* يجب أن يتطابقان مع عدد أقل . :

eeeAiiZuuuuAoooZeeee
   \______________/
    A.* matched, Z still can't match

هذا يحدث عدة مرات ، حتى نصل في النهاية إلى هذا:

eeeAiiZuuuuAoooZeeee
   \__________/
    A.* matched, Z can now match

يمكن أن يتطابق Z الآن ، لذلك يطابق النمط العام:

eeeAiiZuuuuAoooZeeee
   \___________/
    A.*Z matched

على النقيض من ذلك ، فإن التكرار المتردد في A.*?Z يطابق أولاً . قدر الإمكان ، ثم أخذ المزيد . عند الضرورة. هذا ما يفسر سبب العثور على اثنين من التطابقات في الإدخال.

في ما يلي تمثيل مرئي لما يتوافق معه النمطان:

eeeAiiZuuuuAoooZeeee
   \__/r   \___/r      r = reluctant
    \____g____/        g = greedy

مثال: بديل

في العديد من التطبيقات ، فإن المباراتين في المدخل السابق هي ما هو المطلوب ، وبالتالي مترددة .*? يستخدم بدلا من الجشع .* لمنع overmatching. لكن ، بالنسبة لهذا النمط المعين ، هناك بديل أفضل ، باستخدام طبقة الشخصيات المنسوخة.

كما يجد النمط A[^Z]*Z نفس التطابقين كنموذج A.*?Z للإدخال أعلاه ( كما هو موضح في ideone.com ). [^Z] هو ما يسمى بفئة الأحرف المنسوخة : فهو يطابق أي شيء ما عدا Z

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

المراجع

المثال 2: من A إلى ZZ

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

eeAiiZooAuuZZeeeZZfff

هذه هي مطابقات الإدخال أعلاه:

في ما يلي تمثيل مرئي لما يطابق:

         ___n
        /   \              n = negated character class
eeAiiZooAuuZZeeeZZfff      r = reluctant
  \_________/r   /         g = greedy
   \____________/g

مواضيع ذات صلة

هذه هي روابط للأسئلة والأجوبة على التي تغطي بعض المواضيع التي قد تكون ذات أهمية.

يمكن لتكرار الجشع أن يتفوق على أخرى


إنه الفرق بين الكميات الجشعة وغير الجشعة.

النظر في مدخلات 101000000000100 .

باستخدام 1.*1 ، * طماع - سوف يتطابق تمامًا مع النهاية ، ثم يتراجع حتى يتطابق مع 1 ، 1010000000001 مع 1010000000001 .
.*? غير الجشع. * لن يطابق أي شيء ، ولكن سيحاول بعد ذلك مطابقة الأحرف الزائدة حتى يتطابق مع 1 ، وفي النهاية يطابق 101 .

جميع أجهزة القياس لديها وضع غير الجشع:. .+? ، .{2,6}? وحتى .?? .

في حالتك ، يمكن أن يكون نمط مماثل <([^>]*)> - يطابق أي شيء ولكن أكبر من علامة (بالمعنى الدقيق للكلمة ، فإنه يطابق الصفر أو أكثر من الأحرف الأخرى غير > in-between < and > ).

انظر ورقة الغش Quantifier .







regex-greedy