تطابق بسيط لـ C regex من Rob Pike in Go
آب (أغسطس) 2022
في عام 1998 ، كتب روب بايك ، المشهور بـ Go و Plan 9 ، مقارن تعبير عادي بسيط لـ C لـ The Practice of Programming ، وهو كتاب شارك في تأليفه مع زميله Unix Hacker Brian Kernighan. إذا لم تكن قد قرأت "تفسير" Kernighan لهذا الرمز ، فمن المؤكد أنه يستحق 30 دقيقة من الاستثمار الذي تستغرقه لتصفحه ببطء. p>
من خلال تراث Go's C (وتأثير Pike على لغة Go) ، اعتقدت أنني سأرى مدى جودة ترجمة C البرمجية إلى Go ، وما إذا كانت لا تزال أنيقة. p> النسخة الأصلية C
لنلقِ نظرة على رمز المطابقة الأصلي لبايك أولاً. إنه يتعامل فقط مع عدد صغير من الأحرف الأولية للتعبير العادي ، مثل. ، * ، ^ ، و $ ، لكنه مجموعة فرعية مختارة جيدًا ، وفقًا لـ Kernighan ، "تمثل 95٪ من جميع مثيلات" استخدامها بسهولة يوميًا. < / ص>
أنا فقط grep .bash_history الخاص بي لاستخدام grep (كيف meta!) والنسبة المئوية الخاصة بي متشابهة ، على الرغم من أنني أستخدم أيضًا أحرف أولية تم تجاوزها (عادةً \.) في حوالي 10٪ من الاستخدامات. p>
هنا هو المطابق الأصلي 35 سطرًا ج: p> / * match: ابحث عن التعبيرات العادية في أي مكان في النص * / تطابق int (char * regexp ، char * text) { إذا (التعبير العادي [0] == '^') إرجاع المطابقة (regexp + 1 ، نص) ؛ يجب {/ * البحث حتى إذا كانت السلسلة فارغة * / إذا (matchhere (regexp ، text)) العودة 1 ؛ } while (* text ++! = '\ 0') ؛ إرجاع 0 ؛ } / * matchhere: البحث عن التعبير العادي في بداية النص * / int matchhere (char * regexp، char * text) { إذا (regex [0] == '\ 0') العودة 1 ؛ إذا (تعبير عادي [1] == '*') إرجاع matchstar (regexp [0] ، regexp + 2 ، نص) ؛ إذا (regexp [0] == '$' && regexp [1] == '\ 0') إرجاع * النص == '\ 0' ؛ if (* text! = '\ 0' && (regexp [0] == '.' || regexp [0] == * text)) إرجاع المطابقة (التعبير العادي + 1 ، النص + 1) ؛ إرجاع 0 ؛ } / * matchstar: ابحث عن c * regexp في بداية النص * / int matchstar (int c ، char * regex ، char * text) { فعل {/ * a * يطابق صفرًا أو أكثر من المثيلات * / إذا (matchhere (regexp ، text)) العودة 1 ؛ } while (* text! = '\ 0' && (* text ++ == c || c == '.')) ؛ إرجاع 0 ؛ }
جميلة ، أليس كذلك؟ لن أشرح هذا الرمز هنا ؛ يقوم Kernighan بعمل أفضل بكثير مما أفعله في مقالته "A Regular Expression Matcher".
ترجمة |لا تستخدم السلاسل النصية في Go مؤشرات char ، بالطبع ، لكن عمليات فهرسة السلسلة وتقطيع السلاسل مثل النص [1:] متطابقة تمامًا (إذا جاز التعبير). p>
كما يشير Kernighan ، فإن "do-while" نادر جدًا في C ، ولكنه ضروري هنا. على الأرجح للأفضل ، ليس لدى Go وقت ، لذلك أستخدم عبارة if داخل الحلقة وأعود مبكرًا بدلاً من ذلك. أيضًا ، لن تساعدنا ميزة "do-while" هنا لأننا ما زلنا غير قادرين على استخدام تعبيرات الجلب والزيادة مثل * text ++.
هناك عدد من الأشياء تشغل سطورًا أكثر في Go ، ويرجع ذلك جزئيًا إلى عدم وجود "وقت" ، ولكن أيضًا لأنك لا تستطيع فعل عبارات على سطر بدون أقواس. ومع ذلك ، فقد قمت بتحويل سلسلة عبارات if في matchHere إلى مفتاح تبديل بسيط ، مما يجعل هذه الوظيفة موجزة تقريبًا مثل إصدار C.
بعض الأشياء تكون أسهل مع السلاسل في Go ، على سبيل المثال regexp [0] == '$' && regexp [1] == '\ 0' تصبح regexp == "$".
لذلك بدون مزيد من اللغط ، ها هو إصدار Go الخاص بي: p>
آب (أغسطس) 2022
في عام 1998 ، كتب روب بايك ، المشهور بـ Go و Plan 9 ، مقارن تعبير عادي بسيط لـ C لـ The Practice of Programming ، وهو كتاب شارك في تأليفه مع زميله Unix Hacker Brian Kernighan. إذا لم تكن قد قرأت "تفسير" Kernighan لهذا الرمز ، فمن المؤكد أنه يستحق 30 دقيقة من الاستثمار الذي تستغرقه لتصفحه ببطء. p>
من خلال تراث Go's C (وتأثير Pike على لغة Go) ، اعتقدت أنني سأرى مدى جودة ترجمة C البرمجية إلى Go ، وما إذا كانت لا تزال أنيقة. p> النسخة الأصلية C
لنلقِ نظرة على رمز المطابقة الأصلي لبايك أولاً. إنه يتعامل فقط مع عدد صغير من الأحرف الأولية للتعبير العادي ، مثل. ، * ، ^ ، و $ ، لكنه مجموعة فرعية مختارة جيدًا ، وفقًا لـ Kernighan ، "تمثل 95٪ من جميع مثيلات" استخدامها بسهولة يوميًا. < / ص>
أنا فقط grep .bash_history الخاص بي لاستخدام grep (كيف meta!) والنسبة المئوية الخاصة بي متشابهة ، على الرغم من أنني أستخدم أيضًا أحرف أولية تم تجاوزها (عادةً \.) في حوالي 10٪ من الاستخدامات. p>
هنا هو المطابق الأصلي 35 سطرًا ج: p> / * match: ابحث عن التعبيرات العادية في أي مكان في النص * / تطابق int (char * regexp ، char * text) { إذا (التعبير العادي [0] == '^') إرجاع المطابقة (regexp + 1 ، نص) ؛ يجب {/ * البحث حتى إذا كانت السلسلة فارغة * / إذا (matchhere (regexp ، text)) العودة 1 ؛ } while (* text ++! = '\ 0') ؛ إرجاع 0 ؛ } / * matchhere: البحث عن التعبير العادي في بداية النص * / int matchhere (char * regexp، char * text) { إذا (regex [0] == '\ 0') العودة 1 ؛ إذا (تعبير عادي [1] == '*') إرجاع matchstar (regexp [0] ، regexp + 2 ، نص) ؛ إذا (regexp [0] == '$' && regexp [1] == '\ 0') إرجاع * النص == '\ 0' ؛ if (* text! = '\ 0' && (regexp [0] == '.' || regexp [0] == * text)) إرجاع المطابقة (التعبير العادي + 1 ، النص + 1) ؛ إرجاع 0 ؛ } / * matchstar: ابحث عن c * regexp في بداية النص * / int matchstar (int c ، char * regex ، char * text) { فعل {/ * a * يطابق صفرًا أو أكثر من المثيلات * / إذا (matchhere (regexp ، text)) العودة 1 ؛ } while (* text! = '\ 0' && (* text ++ == c || c == '.')) ؛ إرجاع 0 ؛ }
جميلة ، أليس كذلك؟ لن أشرح هذا الرمز هنا ؛ يقوم Kernighan بعمل أفضل بكثير مما أفعله في مقالته "A Regular Expression Matcher".
ترجمة |لا تستخدم السلاسل النصية في Go مؤشرات char ، بالطبع ، لكن عمليات فهرسة السلسلة وتقطيع السلاسل مثل النص [1:] متطابقة تمامًا (إذا جاز التعبير). p>
كما يشير Kernighan ، فإن "do-while" نادر جدًا في C ، ولكنه ضروري هنا. على الأرجح للأفضل ، ليس لدى Go وقت ، لذلك أستخدم عبارة if داخل الحلقة وأعود مبكرًا بدلاً من ذلك. أيضًا ، لن تساعدنا ميزة "do-while" هنا لأننا ما زلنا غير قادرين على استخدام تعبيرات الجلب والزيادة مثل * text ++.
هناك عدد من الأشياء تشغل سطورًا أكثر في Go ، ويرجع ذلك جزئيًا إلى عدم وجود "وقت" ، ولكن أيضًا لأنك لا تستطيع فعل عبارات على سطر بدون أقواس. ومع ذلك ، فقد قمت بتحويل سلسلة عبارات if في matchHere إلى مفتاح تبديل بسيط ، مما يجعل هذه الوظيفة موجزة تقريبًا مثل إصدار C.
بعض الأشياء تكون أسهل مع السلاسل في Go ، على سبيل المثال regexp [0] == '$' && regexp [1] == '\ 0' تصبح regexp == "$".
لذلك بدون مزيد من اللغط ، ها هو إصدار Go الخاص بي: p>
What's Your Reaction?
![like](https://vidianews.com/assets/img/reactions/like.png)
![dislike](https://vidianews.com/assets/img/reactions/dislike.png)
![love](https://vidianews.com/assets/img/reactions/love.png)
![funny](https://vidianews.com/assets/img/reactions/funny.png)
![angry](https://vidianews.com/assets/img/reactions/angry.png)
![sad](https://vidianews.com/assets/img/reactions/sad.png)
![wow](https://vidianews.com/assets/img/reactions/wow.png)