English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

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

التعبيرات النمطية الصفر عرض:

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

أولاً، المفاهيم الأساسية:

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

مثال على الكود:

مثال على الكود الأول:

var str="abZW863";
var reg=/ab(?=[A-Z])/;
console.log(str.match(reg));

في الكود أعلاه، يعني النمط النمطي: تطابق السلسلة التي تتبعها أي حرف كبير "ab". النتيجة النهائية للتطابق هي "ab"، لأن التعبير النمطي الصفر عرض "(?=[A-Z])" لا يتطابق مع أي حرف، إنه يستخدم فقط لتعيين أن الموقع التالي يجب أن يكون حرف كبير.

مثال على الكود الثاني:

var str="abZW863";
var reg=/ab(?![A-Z])/;
console.log(str.match(reg));

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

ثانيًا، مبدأ التطابق:

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

var str="<div>antzone";
var reg=/^(?=<)<[^>]+>\w+/;
console.log(str.match(reg));

يبدأ عملية التطابق كما يلي:
أولاً، يتم الحصول على السيطرة من قبل التعبيرات النمطية "^"، حيث تبدأ العملية التزامنية من الموقع 0 لتحديد الصيغة، إنها تتطابق مع الموقع 0، يحدث التطابق بنجاح، ثم يتم تحويل السيطرة إلى "(?=<)،، لأن "^" هو صفر عرض، لذا "(?=<)" يبدأ أيضًا من الموقع 0 في عملية التطابق، إنه يتطلب أن يكون الموقع إلى اليمين هو حرف "<"، والموقع 0 إلى اليمين هو حرف "<"، يحدث التطابق بنجاح، ثم يتم تحويل السيطرة إلى "<"، لأن "(?=<)" هو صفر عرض أيضًا، لذا يبدأ أيضًا من الموقع 0 في عملية التطابق، يحدث التطابق بنجاح، لا يتم شرح عملية التطابق التالية.

2. الاستدلالات الزائفة السلبية:

مثال على الكود:

var str="abZW863ab88"; 
var reg=/ab(?![A-Z])/g; 
console.log(str.match(reg));

يبدأ عملية التطابق كما يلي:
أولاً، يأخذ الحرف "a" السيطرة من التعبير النمطي، ويبدأ التطابق من الموقع 0، يُنجح التطابق مع الحرف "a"، ثم ينتقل السيطرة إلى "b"، ويبدأ التطابق من الموقع 1، يُنجح التطابق مع الحرف "b"، ثم ينتقل السيطرة إلى "(?![A-Z])"، ويبدأ التطابق من الموقع 2، ويطلب هذا التطابق أن لا يكون هناك حرف كبير على يسار هذا الموقع، بينما يكون الحرف الكبير "Z" على يساره، يفشل التطابق، ثم يعود السيطرة إلى الحرف "a"، ويبدأ التطابق من الموقع 1، يفشل التطابق، ثم يعود السيطرة إلى الحرف "a" ويبدأ التطابق من الموقع 2، يفشل التطابق، ويكرر هذا العمل حتى يبدأ التطابق من الموقع 7، ويُنجح التطابق، ثم ينتقل السيطرة إلى "b"، ويبدأ التطابق من الموقع 8، يُنجح التطابق، ثم ينتقل السيطرة إلى "(?![A-Z])"، ويبدأ التطابق من الموقع 9، ويطلب هذا التطابق أن لا يكون هناك حرف كبير على يساره، يُنجح التطابق، ولكن لن يقوم بالتطابق الفعلي مع الحرف، لذا تكون النتيجة النهائية "ab".

إليك الإضافات

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

تعريف التفسير

الاستدلالات الزائفة هي طريقة واحدة في التعبيرات النمطية
التعبيرات النمطية في علم الكمبيوتر، هي عبارة عن سلسلة من الأحرف تستخدم لوصف أو التطابق مع سلسلة من الأحرف التي تتوافق مع قواعد نحوية معينة. غالبًا ما تستخدم التعبيرات النمطية في محررات النصوص أو أدوات أخرى لبحث وتغيير النصوص التي تتوافق مع نمط معين. يدعم العديد من لغات البرمجة استخدام التعبيرات النمطية لعمليات النصوص. على سبيل المثال، يحتوي Perl على محرك قوي للتعبيرات النمطية. بدأ مفهوم التعبيرات النمطية بانتشاره في أدوات Unix (مثل sed و grep). عادة ما تُكتب التعبيرات النمطية بـ “regex”، الواحدية هي regexp أو regex، والجمع هي regexps أو regexes أو regexen.

الادعاءات الصفرية

تُستخدم للبحث عن شيء موجود قبل أو بعد محتوى معين (لكن ليس جزءًا منه)، أي أنها تشبه \b،^،$ لتعيين موقف يجب أن ي满足 بعض الشروط (أي الادعاءات)، لذا تُدعى أيضًا الادعاءات الصفرية. من الأفضل توضيح ذلك بالأمثلة: يتم استخدام الادعاءات لبيان حقيقة يجب أن تكون صحيحة. يتم استمرار التطابق في التعبيرات العادية فقط إذا كانت الادعاءات صحيحة.

(?=exp) يُدعى أيضًا الادعاء الصفرية الإيجابية المتقدمة، حيث يدعي أن موقفه موجودًا في نفس المكان الذي يمكن تطابق فيه التعبير exp. على سبيل المثال، \b(?=re)\w+\b تطابق الجزء التالي من الكلمة الذي يبدأ بـ re (باستثناء re نفسه)، مثل في البحث عن reading a book. تطابق ading.

var reg = new Regex(@"\w+(?=ing)");
var str = "muing";
Console.WriteLine(reg.Match(str).Value); // يعود إلى mu

(?<=exp) يُدعى أيضًا الادعاء الصفرية الإيجابية المبكرة، حيث يدعي أن موقفه موجودًا في نفس المكان الذي يمكن تطابق فيه التعبير exp. على سبيل المثال، \b\w+(?<=ing\b) تطابق الجزء الأول من الكلمة التي تنتهي بـ ing (باستثناء ing نفسه)، مثل في البحث عن I am reading. تطابق read.

إذا كنت ترغب في إضافة فاصلة كل ثلاثة أرقام في عدد طويل (بالطبع من اليمين إلى اليسار)، يمكنك البحث عن الجزء الذي يجب إضافة الفاصلة إليه ووضعها فيه: ((?=\d)\d{3})+\b، باستخدام هذا البحث على 1234567890 النتيجة هي 234567890.
في هذا المثال، يتم استخدام هذين الاستنتاجين المسبقين معًا: (?<=\s)\d+(?=\s) تطابق الأرقام المفصولة بالفراغات (أعاد التأكيد، لا تشمل هذه الفراغات).

الادعاءات الصفرية السلبية

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

تطابق الكلمة التي تحتوي على q غير متبوعة بالحرف u. ولكن إذا قمت ببعض الاختبارات الإضافية (أو إذا كانت ذاكرتك واضحة بما يكفي لرؤيتها مباشرة)، ستجد أن هذا التعبير يفشل عند وجود q في نهاية الكلمة مثل Iraq، Benq. هذا بسبب أن [^u] يجب أن يتطابق مع حرف، لذا إذا كان q هو الحرف الأخير في الكلمة، فإن [^u] سيطابق الحرف التالي الذي يلي الحرف q (ربما هو فاصلة أو نقطة أو شيء آخر)، وسيطابق \w*\b الكلمة التالية، وبالتالي سيطابق \b\w*q[^u]\w*\b الكلمة بأكملها Iraq fighting. يمكن حل هذا المشكلة باستخدام الادعاءات الصفرية السلبية لأنها تطابق فقط موقفًا واحدًا دون استهلاك أي حروف. الآن، يمكننا حل المشكلة بهذه الطريقة: \b\w*q(?!u)\w*\b.

الاستدلالية غير واسعة التوجه السلبية للتنبؤ، (?!exp)، تُدعي أن موقعها لا يمكنه أن يطابق التعبير exp. على سبيل المثال، \d{3}(?!\d) يطابق ثلاثة أرقام وليس له أي رقم بعد ذلك؛ \b((?!abc)\w)+\b يطابق الكلمة التي لا تحتوي على سلسلة abc متصلة.
بالمثل، يمكننا استخدام (?<!exp)، الاستدلالية غير واسعة التوجه السلبية للتراجع، لتأكيد أن موقعها لا يمكنه أن يطابق التعبير exp: (?<![a-z])\d{7} يطابق سبعة أرقام ليس لها أي حروف صغيرة قبلها.

مثال أكثر تعقيدًا: (?<=<(\w+)>).*(?=<\/\1>) يطابق المحتوى بين علامتي بداية وإنهاء بسيطة من HTML دون خاصيات. (<?=(\w+)>) يحدد هذا المقدار: الكلمة المكتوبة بين الأسهم (مثل <b>)، ثم *(النص العشوائي)، وأخيرًا(?=<\/\1>)، تنطبق على ما تم ذكره مسبقًا؛ الـ\/ هي تحويل للرمز، و\1 هي مرجع لل捕获 الأول، الذي هو ما تم تطابق (\w+)، إذا كان المقدار المسبق هو <b>، فإن النهاية هي </b>، والنموذج يطابق المحتوى بين <b> و</b> (مرة أخرى، دون المقدار المسبق والنهاية نفسها).

بعد ذلك، قد يكون من الصعب فهمها. دعونا نقدم بعض التعديلات:

الاستدلالات تستخدم لتعريف حقيقة يجب أن تكون صحيحة. في تعبيرات النصوص العادية، يتم استمرار التطابق فقط عندما تكون الاستدلالات صحيحة.
الاربعة التالية تستخدم للبحث عن شيء ما قبل أو بعد محتوى معين (لكن ليس هذه المحتويات نفسها)، أي أنها تشبه \b, ^, $ لتحديد موقع يجب أن يكون مطابقًا لشروط معينة (أي الاستدلال)، لذلك يُسمى أيضًا استدلالات غير واسعة التوجه. من الأفضل توضيح ذلك بالمثال:

(?=exp) يُسمى أيضًا صيغة استدلالية غير واسعة التوجه، ويُدعي أن موقعها يُمكنه أن يُطابق التعبير exp. على سبيل المثال، \b\w+(?=ing\b) يطابق الجزء الذي ينتهي بكلمة ing من بداية الكلمة (باستثناء ing نفسها)، مثل البحث في I'm singing while you're dancing.، يطابق sing وdanc.
(?<=exp) يُسمى أيضًا صيغة استدلالية غير واسعة التوجه، ويُدعي أن موقعها يُمكنه أن يُطابق التعبير exp. على سبيل المثال، (?<=\bre)\w+\b يُطابق الجزء الذي يبدأ بكلمة re من نهاية الكلمة (باستثناء re نفسها)، مثل البحث في reading a book، يطابق ading.

إذا كنت تريد إضافة شرطة بين كل ثلاثة أرقام في عدد طويل (بالطبع من اليمين إلى اليسار)، يمكنك البحث عن الجزء الذي يجب إضافة شرطة أمامه وبينه كما يلي: ((?<=\d)\d{3})*\b، واستخدامه للبحث في 1234567890 النتيجة هي 234567890。
في هذا المثال، يتم استخدام هذين الاستنتاجين المسبقين معًا: (?<=\s)\d+(?=\s) تطابق الأرقام المفصولة بالفراغات (أعاد التأكيد، لا تشمل هذه الفراغات).

إضافة ثانية:

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

      ما هو الاستنتاج المسبق غير المتراجع للبعد الصحيح؟ انظر إلى التفسير الرسمي على MSDN

(?= 子表达式)

الاستنتاج المسبق غير المتراجع للبعد الصحيح. يتم التطابق المستمر فقط عندما يتم تطابق التعبير الفرعي في هذا الموقع من اليمين. على سبيل المثال، \w+(?=\d) يتم تطابق كلمة تتبعها أرقام، وليس الأرقام نفسها.

      مثال كلاسيكي: للحصول على محتوى قبل ing من كلمة تنتهي بـ ing

var reg = new Regex(@"\w+(?=ing)");
var str = "muing";
Console.WriteLine(reg.Match(str).Value); // يعود إلى mu

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

     دعونا نرى الكود أدناه

var reg = new Regex(@"a(?=b)c");
var str = "abc";
Console.WriteLine(reg.IsMatch(str)); // يعود إلى false

      لماذا يعود الناتج إلى false؟

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

     بسبب أن b يتبع a، فإنه في هذه الحالة تم العثور على محتوى التطابق a (من المعروف من المثال الأول، يتم العثور فقط على a وليس على محتوى تطابق exp)، وقد تم حل جزء a(?=b)c من الآن، ويجب حل مشكلة تطابق c، في هذه الحالة يجب تطابق c من حيث يبدأ النص abc، وفقًا للتعريف الرسمي، نعلم أنه من موقع التعبير الفرعي إلى اليمين، لذا فهو من موقع b، ولكن b لا تطابق c المتبقية من a(?=b)c، لذا abc لا تطابق a(?=b)c.

     إذا كان يجب على الأعلى التطابق، كيف يجب كتابة النمط النموذجي؟

     الإجابة هي: a(?=b)bc

     بالطبع، قد يقول شخص ما أن abc تطابق مباشرة، لماذا نزعج أنفسنا بهذا؟ بالطبع لا يجب أن نزعج أنفسنا بهذا، فقط لشرح كيف يعمل استدلال التنبؤي الصريح للنهاية؟ نفس المبدأ ينطبق على الاستدلالات العريضة الأخرى أيضًا!

إضافة ثالثة

(?=exp): استدلال التنبؤي الصريح للنهاية، يستدعي أن يمكن تطابق التعبير exp في موضع هذا

#تطابق ما بعد _path، النتيجة product
  'product_path'.scan /(product)(?=_path)/

(?<=exp): استدلال التراجع الصريح للبداية، يستدعي أن يمكن تطابق التعبير exp في موضع هذا

#تطابق ما قبل name:، النتيجة wangfei
'name:wangfei'.scan /(?<=name:)(wangfei)/ #wangfei

(?!exp): استدلال التنبؤي العريض للنهاية، يستدعي أن لا يمكن تطابق التعبير exp في هذا الموضع

#تطابق ما بعد _path
'product_path'.scan /(product)(?!_path)/  #nil
#تطابق ما بعد _url
'product_path'.scan /(product)(?!_url)/  #product

(?!exp): استدلال التراجع العريض للبداية لا يمكنه تطابق التعبير exp

#تطابق ما قبل name:
'name:angelica'.scan /(?<!name:)(angelica)/  #nil
#تطابق ما قبل nick_name:
'name:angelica'.scan /(?<!nick_name:)(angelica)/#angelica

المحرر قد ضاق من هذا الشئ، سنتشارك شيء جيد لاحقاً، اليوم لننام ونغسل

سيكون لك حبك