العربية

أدوات النص واليومية · مجموعة أدوات النص

من Kleene إلى JavaScript: تاريخ قصير للتعبيرات العادية

· خلفية

التعبيرات العادية جافا سكريبت تاريخ الحوسبة

مخطط زمني يربط بين التعبيرات التلقائية المحدودة و Unix grep و Perl و JavaScript التعبيرات العادية
الرسم التوضيحي المتجه الأصلي ToolAcre

يتتبع التعبيرات العادية من نظرية الأتمتة في الخمسينيات من القرن الماضي وحتى ed وgrep وPerl إلى نكهة JavaScript في كل متصفح، موضحًا سبب ظهور بناء الجملة بالطريقة التي تظهر بها والميزات التي وصلت ومتى.

اللغة الصغيرة الغريبة التي يعرفها الجميع جزئيًا - لماذا تبدو صياغة التعبير العادي قديمة وغير متسقة

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

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

أحداث كليني المنتظمة - رياضيات الخمسينيات من القرن الماضي التي أعطتنا النجم

قدمت أعمال ستيفن كول كلين حول الأتوماتا المحدودة و"الأحداث المنتظمة" الجذر النظري خلال الخمسينيات. وصف تدوينه مجموعات من تسلسلات الرموز باستخدام العمليات بما في ذلك الاتحاد والتسلسل والإغلاق. أصبحت عملية الإغلاق هي نجمة الكليني: `A*` تعني صفر أو أكثر من التكرارات المستخرجة من A، وليس مجرد "تكرار مرة واحدة أو أكثر".

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

Thompson وed وgrep - كيف دخل التعبير العادي إلى تحرير النص في أواخر الستينيات وأوائل السبعينيات من القرن الماضي أدوات يونكس

ربط كين طومسون النظرية بأدوات النص العاملة. وصفت اتصالاته 1968 الخاصة بمقال ACM تجميع التعبيرات النمطية في كود الآلة للبحث عن النص، وقد ساعد عمله التحريري السابق في وضع مطابقة الأنماط داخل سلالة يونكس. استخدم محرر `ed` التعبيرات العادية في الأوامر التي حددت الخطوط المطابقة وحوّلتها.

الاسم `grep` جاء من أمر `ed` الذي يتم تقديمه بشكل شائع كـ `g/re/p`: حدد الأسطر المطابقة لتعبير عادي بشكل عام واطبعها. لم تكن grep المبكرة عبارة عن مجموعة خيارات GNU اليوم، وتختلف أشكال POSIX الأساسية والممتدة لاحقًا. كان التغيير الدائم عمليًا: فقد أصبحت اللغة الرمزية الصغيرة هي الواجهة اليومية للعثور على النص.

Perl و PCRE - الامتدادات التي أضافت محددات كمية غير جشعة، وLookaround، وصياغة الجملة التي تنسخها معظم الأدوات اليوم

جعل بيرل لغة نمطية أكثر ثراءً مركزية للبرمجة ذات الأغراض العامة. عبر إصداراته، واجه المبرمجون مجموعات الالتقاط، والمراجع الخلفية، والتأكيدات، ومحددات الكمية البطيئة ومعدلات الأنماط في نظام بيئي واحد واضح للغاية. يسجل توثيق Perl 5 بنيات مثل `*?` للحد الأدنى من المطابقة و`(?=...)` للتطلع الإيجابي، إلى جانب العديد من الميزات الغائبة عن نماذج Unix الأقدم.

من الأسلم أن نقول إن بيرل شاع هذا الأسلوب بدلاً من أن ننسب إليه الفضل في اختراع كل امتداد. PCRE عرض عمدًا بناء جملة متوافقًا مع لغة Perl، بينما تبنت المحركات الأخرى أفكارًا مختارة ورفضت أفكارًا أخرى. يمكن أن تخفي علامات الترقيم المشتركة دلالات مختلفة أو سلوك Unicode أو الأداء. وبالتالي فإن عبارة "شبيهة بـ Perl" تصف تأثيرًا واسع النطاق، وليس ضمانًا بأن نمط Perl قابل للنقل.

قام بيرل بنشر لغة نمطية عملية أكبر. تم استعارة المحركات اللاحقة بشكل انتقائي

JavaScript قام بتوحيد كائنات `RegExp` الخاصة به وصياغته الحرفية، مثل `/pattern/gi`، للبرامج التي تعمل في المتصفحات وبيئات ECMAScript الأخرى. تشتمل نكهتها على مجموعات الالتقاط وغير الالتقاط، والمراجع الخلفية، والنظرة الأمامية، ومحددات الكمية البطيئة، وفئات الشخصيات. أضافت الإصدارات اللاحقة مجموعات التقاط مسماة وتأكيدات بحثية في مواصفات ES2018.

JavaScript ليس PCRE أو Python بمحددات مختلفة. يعتمد توفر الميزة على إصدار ECMAScript الذي ينفذه المحرك، وتعد العلامات جزءًا من السلوك وليس الزخرفة. يعد دليل التعبير العادي لـ MDN هو المرجع العملي ذي الصلة لبناء جملة المتصفح، ولكن حتى أمثلة JavaScript الصالحة قد تعتمد على إشارات لا تكشفها واجهة معينة.

حصلت JavaScript على مجموعات مسماة ونظرت إلى الخلف في ES2018، ولكن لا تزال المحركات والأعلام مختلفة

تضع المتصفحات محرك التعبير العادي JavaScript بالقرب من العمل النصي العادي. يمكن للصفحة تجميع نمط وعدد المطابقات وتمريره إلى `String.prototype.replace` دون إرسال النص إلى خدمة تعبير عادي متخصصة. يجعل هذا التوفر واجهة البحث والاستبدال من جانب المتصفح ممكنة، على الرغم من أنه لا يزال يتعين فحص الصفحة المحيطة بشكل منفصل للحصول على مطالبات الخصوصية الأوسع.

يستدعي تنفيذ ToolAcre `new RegExp` داخل `compilePattern`، ويكتشف فشل الترجمة ويعيد خطأ بدلاً من الرمي. `findReplace` يقوم بحساب التطابقات قبل تطبيق عملية الاستبدال القياسية. ونتيجة لذلك، فإن JavaScript الرموز المميزة البديلة مثل مراجع الالتقاط تتبع سلسلة المضيف API؛ إن بناء جملة regex وبناء جملة الاستبدال هما لغتان مرتبطتان ولكنهما مختلفتان.

ما لا يغطيه هذا هو نظرية اللغة الرسمية التي تتجاوز الأساسيات والجوانب الداخلية لأداء المحرك

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

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

الوجبات الجاهزة - وضع التعبير العادي لمجموعة أدوات النص هو نكهة JavaScript، لذلك تعمل الأنماط من وثائق المتصفح كما هو مكتوب

يظهر الميراث العملي في ToolAcre: قم بتشغيل Regex ويتم تجميع نص البحث بواسطة محرك JavaScript الخاص بالمتصفح. اترك Regex معطلاً وسيتم الهروب من الأحرف الأولية، مما يجعل البحث حرفيًا. تقوم الكلمة بأكملها بتغليف التعبير بحدود ASCII ذات النمط ``، بينما تتحكم حساسية حالة الأحرف فيما إذا كانت العلامة `i` مصاحبة للعلامة `g` العامة الموجودة دائمًا.

تصحح هذه التفاصيل الأخيرة الوعد العام للمخطط التفصيلي بأن أنماط توثيق المتصفح تعمل كما هو مكتوب. لا يعرض ToolAcre علامات متعددة الأسطر أو النقاط أو علامات Unicode، لذا فإن الأمثلة التي تتطلب `m` أو `s` أو `y` أو `u` أو `v` تحتاج إلى تعديل ولا يمكن إعادة إنتاج بعضها هناك. استخدم الأداة لاختبار أنماط JavaScript المدعومة، وقراءة عدد الاستبدالات، والتراجع قبل التحسين.