التعبيرات النمطية المتوافقة مع لغة بيرل
مكتبة التعبيرات النمطية المتوافقة مع بيرل ( PCRE ) هي مكتبة مكتوبة بلغة C ، تُنفذ محركًا للتعبيرات النمطية ، مستوحى من إمكانيات لغة برمجة بيرل . بدأ فيليب هازل بكتابة PCRE في صيف عام 1997. [ 3 ] يتميز بناء جملة PCRE بقوة ومرونة أكبر بكثير من أي من نوعي التعبيرات النمطية POSIX (BRE، ERE) [ 4 ] ومن العديد من مكتبات التعبيرات النمطية الأخرى.
رغم أن مشروع PCRE كان يهدف في الأصل إلى تحقيق تكافؤ الميزات مع لغة Perl، إلا أن التطبيقين ليسا متطابقين تمامًا. خلال مرحلة PCRE 7.x و Perl 5.9.x، نسق المشروعان عملية التطوير، حيث تم نقل الميزات بينهما في كلا الاتجاهين. [ 5 ]
في عام ٢٠١٥، تم إصدار نسخة معدلة من PCRE بواجهة برمجة تطبيقات (API) مُحسّنة. البرنامج الأصلي، الذي يُسمى الآن PCRE1 (سلسلة الإصدارات من ١.xx إلى ٨.xx)، تم إصلاح أخطائه، لكن لم يتم تطويره بعد ذلك. على الرغم من أنه لا يزال يُستخدم في بعض الأنظمة القديمة، إلا أن PCRE1 لم يعد يُصان بشكل فعال، ومن المتوقع أن يكون الإصدار الحالي ٨.٤٥ هو الأخير. أما برنامج PCRE2 الجديد (سلسلة الإصدارات ١٠.xx) فقد شهد عددًا من الإضافات والتحسينات البرمجية، وهو البرنامج الذي يتم تطويره حاليًا.
تتضمن العديد من البرامج مفتوحة المصدر البارزة ، مثل خوادم HTTP مثل Apache و Nginx ، ولغات البرمجة النصية PHP و R ، مكتبة PCRE؛ ويمكن للبرامج الاحتكارية أن تحذو حذوها، لأن المكتبة مرخصة بموجب ترخيص BSD. ابتداءً من إصدار Perl 5.10، أصبحت PCRE متاحة أيضًا كبديل لمحرك التعبيرات النمطية الافتراضي في Perl من خلال re::engine::PCREالوحدة النمطية.
يمكن بناء المكتبة على أنظمة يونكس وويندوز والعديد من البيئات الأخرى. يتم توزيع PCRE2 مع غلاف POSIX C، [ ملاحظة 1 ] والعديد من برامج الاختبار، وبرنامج الأداة المساعدة pcregrep/ pcre2grepالذي يتم بناؤه بالتزامن مع المكتبة.
سمات
دعم المترجم الفوري
يمكن تفعيل المُصرّف الفوري عند إنشاء مكتبة PCRE2. يُمكن تحقيق تحسينات كبيرة في الأداء عندما (على سبيل المثال) يستخدم البرنامج المُستدعي هذه الميزة مع أنماط متوافقة تُنفّذ بشكل متكرر. تمت كتابة دعم المُصرّف الفوري بواسطة زولتان هيرتزج، وهو غير مُضمّن في غلاف POSIX.
إدارة مرنة للذاكرة
قد يُمثل استخدام مكدس النظام للتراجع مشكلة في PCRE1، ولذلك تم تغيير هذه الخاصية في PCRE2. يُستخدم الآن الكومة لهذا الغرض، ويمكن تحديد حجمها الإجمالي. أما مشكلة تجاوز سعة المكدس ، التي كانت تظهر بشكل متكرر في PCRE1، فقد تم حلها في PCRE2 بدءًا من الإصدار 10.30 (2017).
قواعد هروب متسقة
على غرار لغة بيرل، تتميز لغة PCRE2 بقواعد هروب ثابتة: يمكن هروب أي حرف غير أبجدي رقمي ليُشير إلى قيمته الحرفية بإضافة شرطة \مائلة عكسية (\) قبل الحرف. عادةً ما يُعطي أي حرف أبجدي رقمي مسبوق بشرطة مائلة عكسية معنىً خاصًا. في حال لم يتم تعريف التسلسل على أنه خاص، يحدث خطأ. يختلف هذا عن لغة بيرل، التي تُظهر خطأً فقط في وضع التحذير (لا تحتوي PCRE2 على وضع تحذير). في التعبيرات النمطية الأساسية لنظام POSIX، كانت الشرطة المائلة العكسية تُستخدم أحيانًا للهروب من الأحرف غير الأبجدية الرقمية (مثلاً \.)، وأحيانًا أخرى لإضافة ميزة خاصة (مثلاً \(\)).
فئات الأحرف الموسعة
يدعم النظام فئات الأحرف المكونة من حرف واحد بالإضافة إلى أسماء POSIX الأطول. على سبيل المثال، \dيطابق أي رقم تمامًا كما [[:digit:]]هو الحال في تعابير POSIX النمطية.
المطابقة الدنيا (المعروفة أيضًا باسم "غير الجشعة")
يمكن وضع الحرف "a" ?بعد أي مُحدد تكرار للإشارة إلى استخدام أقصر تطابق. الوضع الافتراضي هو محاولة البحث عن أطول تطابق أولاً ثم الرجوع إلى التطابقات الأقصر: على سبيل المثال، a.*?bسيطابق الحرف "ab" الأول في "ababab"، بينما a.*bسيطابق الحرف "a" السلسلة بأكملها.
إذا Uتم تعيين العلامة، فإن المحددات الكمية تكون غير جشعة (كسولة) بشكل افتراضي، بينما ?يجعلها ذلك جشعة.
خصائص أحرف يونيكود
يُعرّف يونيكود عدة خصائص لكل حرف. يمكن للأنماط في PCRE2 مطابقة هذه الخصائص؛ على سبيل المثال، سيطابق النمط سلسلة نصية تبدأ بأي علامة ترقيم مفتوحة وتنتهي بأي علامة ترقيم مغلقة، مثل . يمكن التحكم في مطابقة بعض الأحرف الخاصة "العادية" بواسطة خصائص يونيكود عند تفعيل خيار التجميع PCRE2_UCP. يمكن تفعيل هذا الخيار لنمط ما عن طريق تضمينه في بداية النمط. يُغيّر هذا الخيار سلوك الأحرف الخاصة التالية: ، ، ، ، ، ، ، ، وبعض فئات أحرف POSIX. على سبيل المثال، يتم توسيع مجموعة الأحرف التي يُطابقها النمط (أحرف الكلمات) لتشمل الأحرف والحروف المُشكّلة كما هو مُعرّف في خصائص يونيكود. هذه المطابقة أبطأ من المطابقة العادية ( ASCII فقط) غير المُعتمدة على UCP. تجدر الإشارة إلى أن خيار UCP يتطلب أن تكون المكتبة قد بُنيت لتضمين دعم يونيكود (وهذا هو الإعداد الافتراضي لـ PCRE2). دعمت الإصدارات الأولى جدًا من PCRE1 رمز ASCII فقط. لاحقًا، تمت إضافة دعم UTF-8 . تمت إضافة دعم UTF-16 في الإصدار 8.30، ودعم UTF-32 في الإصدار 8.32. لطالما دعم PCRE2 جميع ترميزات UTF الثلاثة.\p{Ps}.*?\p{Pe}[abc](*UCP)\B\b\D\d\S\s\W\w\w
مطابقة متعددة الأسطر
^ويمكن $أن تتطابق في بداية ونهاية السلسلة فقط، أو في بداية ونهاية كل "سطر" داخل السلسلة، وذلك حسب الخيارات التي تم تعيينها.
خيارات سطر جديد/فاصل أسطر
عند تجميع PCRE، يتم تحديد سطر جديد افتراضي. يؤثر نوع السطر الجديد/فاصل الأسطر المُفعّل على موضع اكتشاف PCRE ^لبدايات ونهايات الأسطر $(في وضع الأسطر المتعددة)، بالإضافة إلى ما يطابق النقطة (بغض النظر عن وضع الأسطر المتعددة، إلا إذا (?s)تم تعيين خيار dotall). كما يؤثر على إجراء مطابقة PCRE (منذ الإصدار 7.0): عندما يفشل نمط غير مُثبّت في المطابقة عند بداية تسلسل سطر جديد، يتقدم PCRE متجاوزًا تسلسل السطر الجديد بأكمله قبل إعادة محاولة المطابقة. إذا كان خيار السطر الجديد البديل المُفعّل يتضمن CRLF كأحد فواصل الأسطر الصالحة، فإنه لا يتخطى \nCRLF إذا كان النمط يحتوي على مراجع محددة \rأو \nمراجع (منذ الإصدار 7.3). منذ الإصدار 8.10، يطابق الحرف الخاص \Nدائمًا أي حرف بخلاف أحرف فواصل الأسطر. وله نفس السلوك كما .لو لم يكن خيار dotall (?s)مُفعّلًا.
يمكن تعديل خيار سطر جديد باستخدام خيارات خارجية عند تجميع PCRE وتشغيله. توفر بعض التطبيقات التي تستخدم PCRE للمستخدمين إمكانية تطبيق هذا الإعداد من خلال خيار خارجي. لذا، يمكن أيضًا تحديد خيار سطر جديد في بداية النمط باستخدام أحد الخيارات التالية:
(*LF)السطر الجديد هو حرف تغذية السطر. ويمكن مطابقة فواصل الأسطر المقابلة باستخدام\n.(*CR)السطر الجديد هو إرجاع المؤشر إلى بداية السطر . ويمكن مطابقة فواصل الأسطر المقابلة مع\r.(*CRLF)سطر جديد/فاصل أسطر هو إرجاع المؤشر إلى بداية السطر متبوعًا بتغذية سطر. ويمكن مطابقة فواصل الأسطر المقابلة مع\r\n.(*ANYCRLF)أيٌّ من العناصر المذكورة أعلاه في البيانات سيؤدي إلى معالجة الأسطر الجديدة. يمكن مطابقة فواصل الأسطر المقابلة باستخدام أو باستخدام . انظر أدناه للاطلاع على الإعدادات والخيارات المتعلقة بما يطابق علامة الخط المائل العكسي R.(?:\r\n?|\n)\R(*ANY)أي مما سبق بالإضافة إلى فواصل الأسطر الخاصة بنظام يونيكود.
عندما لا يكون الوضع UTF-8، يمكن مطابقة فواصل الأسطر المقابلة مع [ ملاحظة 2 ] أو .(?:\r\n?|\n|\x0B|\f|\x85)\R
في وضع UTF-8، يتم التعرف على حرفين إضافيين كفواصل أسطر باستخدام (*ANY):
- LS (فاصل الخطوط، U+2028)،
- PS (فاصل الفقرات، U+2029).
في نظام التشغيل ويندوز، في البيانات غير المتوافقة مع يونيكود، يكون لبعض ANYأحرف فاصل الأسطر معانٍ أخرى.
على سبيل المثال، \x85يمكن مطابقة علامة الحذف الأفقية، وإذا تمت مصادفتها أثناء ANYسريان السطر الجديد، فسيتم تشغيل معالجة السطر الجديد.
انظر أدناه للاطلاع على الإعدادات والخيارات المتعلقة بما يطابق علامة الخط المائل العكسي R.
خيارات Backslash-R
عند تجميع PCRE، يتم اختيار إعداد افتراضي للمطابقة \R. يمكن أن يكون الإعداد الافتراضي إما مطابقة فواصل الأسطر التي تُطابق ANYCRLF أو تلك التي تُطابق ANY. يمكن تجاوز الإعداد الافتراضي عند الضرورة بإضافة `\n` (*BSR_UNICODE)أو (*BSR_ANYCRLF)`\n` في بداية النمط. يمكن توفير خيار إضافي إلى جانب الخيار `\n`، على سبيل المثال `\n` . كما يمكن تغيير خيارات `\n` باستخدام خيارات خارجية من قِبل التطبيق الذي يستدعي PCRE2، عند تجميع النمط.(*newline)(*BSR..)(*BSR_UNICODE)(*ANY)rest-of-pattern
بداية خيارات النمط
خيارات فاصل الأسطر كما هو (*LF)موثق أعلاه؛ خيارات الشرطة المائلة العكسية R كما هو (*BSR_ANYCRLF)موثق أعلاه؛ خيار خصائص أحرف Unicode (*UCP)الموثق أعلاه؛ (*UTF8)الخيار الموثق على النحو التالي: إذا تم تجميع PCRE2 مع دعم UTF(*UTF) ، فيمكن استخدام الخيار الموجود في بداية النمط بدلاً من تعيين خيار خارجي لاستدعاء وضع UTF-8 أو UTF-16 أو UTF-32.
المراجع الخلفية
قد يشير النمط إلى نتائج مطابقة سابقة. على سبيل المثال، (a|b)c\1سيطابق إما "aca" أو "bcb" ولن يطابق، على سبيل المثال، "acb".
الأنماط الفرعية المسماة
(...)يمكن تسمية النمط الفرعي (المحاط بأقواس، مثل ) بإضافة حرف بادئ ?P<name>بعد القوس المفتوح. تُعدّ الأنماط الفرعية المسماة ميزةً استعارتها مكتبة PCRE من التعبيرات النمطية في بايثون .
تم اعتماد هذه الميزة لاحقًا في لغة بيرل، لذا يمكن الآن تعريف المجموعات المسماة باستخدام (?<name>...)أو (?'name'...)، بالإضافة إلى (?P<name>...). ويمكن الإشارة إلى المجموعات المسماة باستخدام، على سبيل المثال: (?P=name)(صيغة بايثون) أو \k'name'(صيغة بيرل).
البرامج الفرعية
بينما توفر الإشارة المرجعية آلية للإشارة إلى جزء من الموضوع سبق أن طابق نمطًا فرعيًا، فإن الروتين الفرعي يوفر آلية لإعادة استخدام نمط فرعي أساسي مُعرَّف مسبقًا. خيارات النمط الفرعي، مثل استقلالية حالة الأحرف، ثابتة عند تعريف النمط الفرعي. (a.c)(?1)سيطابق النمط الفرعي "aacabc" أو "abcadc"، بينما لن يطابقه استخدام الإشارة المرجعية ، على الرغم من أن كليهما سيطابق "aacaac" أو "abcabc". يدعم PCRE أيضًا بنية Oniguruma(a.c)\1 غير الخاصة بلغة Perl للروتينات الفرعية. يتم تحديدها باستخدام أو .\g<subpat-number>\g<subpat-name>
التجميع الذري
التجميع الذري هو طريقة لمنع التراجع في النمط. على سبيل المثال، a++bcسيطابق أكبر عدد ممكن من حرف "a" ولن يتراجع أبدًا لتجربة حرف أقل.
التأكيدات المتعلقة بالتطلع إلى الأمام والنظر إلى الوراء
| التأكيد | انظر إلى الوراء | نظرة مستقبلية |
|---|---|---|
| إيجابي | (? < = النمط ) | (؟ = نمط ) |
| سلبي | (? < ! نمط ) | (؟ ! نمط ) |
| تأكيدات النظر إلى الوراء والنظر إلى الأمام في التعبيرات النمطية في لغة بيرل | ||
قد تُشير الأنماط إلى أن النص السابق أو اللاحق يحتوي على نمط دون استهلاك النص المطابق (تأكيد العرض الصفري). على سبيل المثال، \w+(?=\t)يُطابق الرمز / / كلمة متبوعة بعلامة جدولة ، دون تضمين علامة الجدولة نفسها.
لا يمكن أن تكون تأكيدات النظر إلى الخلف ذات طول غير مؤكد (على عكس لغة بيرل) حيث يمكن أن يكون لكل فرع طول ثابت مختلف.
\Kيمكن استخدام هذه الطريقة في نمط لإعادة ضبط بداية المطابقة الكاملة الحالية. يوفر هذا نهجًا بديلًا مرنًا لتأكيدات البحث المسبق، لأن الجزء المهمل من المطابقة (الجزء الذي يسبقه \K) ليس بالضرورة أن يكون ثابت الطول.
تسلسلات الهروب للتأكيدات ذات العرض الصفري
مثال \bعلى مطابقة "حدود الكلمات" ذات العرض الصفري، على غرار .(?<=\W)(?=\w)|(?<=\w)(?=\W)|^|$
تعليقات
يبدأ التعليق بـ (?#وينتهي عند القوس الختامي التالي.
الأنماط المتكررة
يمكن للنمط أن يشير إلى نفسه بشكل متكرر أو إلى أي نمط فرعي. على سبيل المثال، سيطابق النمط أي تركيبة من الأقواس المتوازنة وحرف "a".\((a*|(?R))*\)
عبارات عامة
يمكن لتعبيرات PCRE تضمين عدد معين ، حيث يمثل n رقمًا ما. سيؤدي هذا إلى استدعاء دالة خارجية معرفة من قبل المستخدم عبر واجهة برمجة تطبيقات PCRE، ويمكن استخدامه لتضمين أي كود برمجي في نمط معين.(?Cn)
الاختلافات عن بيرل
تشمل الاختلافات بين PCRE2 و Perl (اعتبارًا من Perl 5.9.4) على سبيل المثال لا الحصر ما يلي: [ 6 ]
حتى الإصدار 10.30، كانت المطابقات المتكررة ذرية في PCRE وغير ذرية في Perl
هذا يعني أن ذلك سيتطابق في لغة بيرل ولكن ليس في PCRE2 حتى الإصدار 10.30."<<!>!>!>><>>!>!>!>"=~ /^(<(?:[^<>]+|(?3)|(?1))*>)()(!>!>!>)$/
?تختلف قيمة مخزن الالتقاط المشتق من المُكمِّم (تطابق مرة واحدة أو صفر مرات) عند تضمينه في مخزن التقاط مُكمَّم آخر
في لغة بيرل ، سيؤدي ذلك إلى احتواء "a" واحتواء ، ولكن في لغة PCRE سيؤدي ذلك إلى احتواء "b"."aba"=~ /^(a(b)?)+$/;$1$2undef$2
يسمح PCRE بإعطاء مخازن الالتقاط المسماة أسماءً رقمية؛ بينما يشترط Perl أن يتبع الاسم قاعدة الكلمات المجردة.
هذا يعني أن \g{}الأمر غير غامض في لغة بيرل، ولكنه قد يكون غامضًا في لغة PCRE.
لم يعد هذا الأمر يمثل فرقاً منذ إصدار PCRE 8.34 (الذي صدر في 15 ديسمبر 2013)، والذي لم يعد يسمح بأن تبدأ أسماء المجموعات برقم. [ 7 ]
يسمح برنامج PCRE بأن تكون البدائل ضمن فترة النظر إلى الوراء بأطوال مختلفة
في سياق تأكيدات البحث المسبق، يتطلب كل من PCRE و Perl أنماطًا ذات طول ثابت.
أي أن كلاً من PCRE و Perl لا يسمحان باستخدام الأنماط ذات الطول المتغير باستخدام المحددات الكمية داخل تأكيدات البحث المسبق.
ومع ذلك، يتطلب Perl أن تكون جميع الفروع البديلة لتأكيد البحث عن شيء ما بنفس الطول، بينما يسمح PCRE لتلك الفروع البديلة بأن يكون لها أطوال مختلفة عن بعضها البعض طالما أن كل فرع لا يزال له طول ثابت.
لا يدعم PCRE بعض تركيبات Perl "التجريبية".
مثل (??{...})(دالة رد نداء يتم تقييم إرجاعها كجزء من النمط) ولا (?{})البنية، على الرغم من أنه يمكن محاكاة الأخيرة باستخدام (?Cn).
كما أن أفعال التحكم في التكرار التي تمت إضافتها في سلسلة Perl 5.9.x غير مدعومة أيضًا.
يتوفر دعم أفعال التحكم التجريبية للتراجع (المضافة في Perl 5.10) في PCRE منذ الإصدار 7.3.
هم (*FAIL)، (*F)، (*PRUNE)، (*SKIP)، (*THEN)، (*COMMIT)، و (*ACCEPT).
لا يتم دعم استخدام بيرل للوسائط مع أفعال التحكم في التراجع بشكل عام.
لاحظ مع ذلك أنه منذ الإصدار 8.10، يدعم PCRE الأفعال التالية مع وسيط محدد: (*MARK:markName)، (*SKIP:markName)، (*PRUNE:markName)، و (*THEN:markName).
منذ الإصدار 10.32، يدعم PCRE2 (*ACCEPT:markName)، (*FAIL:markName)و (*COMMIT:markName).
تختلف لغتا PCRE وPerl قليلاً في مدى تحملهما للتركيبات الخاطئة
يسمح Perl باستخدام المحددات الكمية على (?!...)البنية، وهو أمر لا معنى له ولكنه غير ضار (وإن كان غير فعال)؛ ينتج PCRE خطأ في الإصدارات السابقة لـ 8.13.
يفرض PCRE حدًا صارمًا على عمق الاستدعاء الذاتي، بينما لا يفرض Perl ذلك.
مع خيارات البناء الافتراضية، ستفشل عملية المطابقة بسبب الحد الأقصى، لكن لغة بيرل ستطابق هذا بشكل صحيح."bbbbXcXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"=~ /.X(.+)+X/
يستخدم بيرل الذاكرة الديناميكية للتكرار وليس لديه حد صارم لعمق التكرار، بينما يحتوي PCRE2 على حد افتراضي في وقت الترجمة يمكن تعديله لأعلى أو لأسفل بواسطة التطبيق المستدعي.
تَحَقّق
باستثناء النقاط المذكورة أعلاه، فإن PCRE قادر على اجتياز الاختبارات في t/op/re_testsملف Perl " "، وهو أحد اختبارات الانحدار الرئيسية على مستوى بناء الجملة لمحرك التعبيرات النمطية في Perl.
انظر أيضاً
ملاحظات ومراجع
ملحوظات
مراجع
- ↑ الإصدار النهائي من PCRE1: https://lists.exim.org/lurker/message/20210615.162400.c16ff8a3.en.html
- ↑ الإصدارات: https://github.com/PCRE2Project/pcre2/releases
- ↑ Exim وPCRE: كيف اختطفت البرمجيات الحرة حياتي (ديسمبر 1999)، بقلم فيليب هازل ، ص 7: https://www.ukuug.org/events/winter99/proc/PH.ps
ماذا عن PCRE؟
- كُتبت في صيف عام 1997، وتم وضعها على موقع بروتوكول نقل الملفات (FTP).
- عثر الناس عليه، وبدأوا بإنشاء قائمة بريدية.
- وقد طرأت بعض التحسينات الطفيفة.
- ↑
- التعبير النمطي - معيار POSIX: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html
- الأدوات المساعدة § تدوين مطابقة الأنماط: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/V3_chap02.html#tag_18_13
- التعريفات الأساسية § التعابير النمطية الأساسية: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/V1_chap09.html#tag_09_03
- الأساس المنطقي § التعابير النمطية: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/xrat/V4_xbd_chap09.html#tag_21_09
- ↑ PCRE2 - التعبيرات النمطية المتوافقة مع لغة بيرل (واجهة برمجة التطبيقات المُعدّلة) (2020)، من جامعة كامبريدج : https://pcre.org/pcre2.txt
- ↑ الاختلافات بين PCRE2 وPerl (13 يوليو 2019)، بقلم فيليب هازل : https://www.pcre.org/current/doc/html/pcre2compat.html
- ↑ اقتباس من سجل تغييرات PCRE ( https://www.pcre.org/original/changelog.txt ): "لم يعد Perl يسمح بأسماء المجموعات التي تبدأ بأرقام، لذلك قمت بإجراء هذا التغيير أيضًا في PCRE."
- ↑ سجل التغييرات لـ PCRE2: https://www.pcre.org/changelog.txt
روابط خارجية
- الموقع الرسمي

- قائمة بريدية لتطوير PCRE: https://groups.google.com/g/pcre2-dev
- نظام تتبع الأخطاء في مشروع PCRE: https://github.com/PCRE2Project/pcre2/issues
- مطابقة الأنماط باستخدام التعابير النمطية (2010-03-02)، بقلم نيك ماكلارين وفيليب هازل: https://www-uxsup.csx.cam.ac.uk/courses/moved.REs/paper.pdf
- pcre 8.43 (2019-04) - ويندوز سيجوين x86-64: https://www-uxsup.csx.cam.ac.uk/pub/windows/cygwin/x86_64/release/pcre/
- مطابقة الأنماط
- مكتبات لغة البرمجة C
- بيرل
- التعبيرات النمطية
- البرامج التي تستخدم ترخيص BSD
