استخدام Regular Expression في تهيئة النصوص.

نشره أحمد أبوزيد في

مؤخراً كان علي القيام بتنسيق عدداً من الملفات الكبيرة، ونظراً لضيق الوقت كان يجب تقليص العمل اليدوي لأقل وقت ممكن، الملفات كانت تحتوي على سطور خالية، ومسافات في نهاية السطور وبعض المحارف التي يجب التخلص منها، والكثير من الكلمات التي يجب استبدالها، افتراضياً كنت سأقوم بعمل هذا يدوياً، لكن قررت التعرف أكثر على التعابير النمطية التي تدعى Regular Expressions أو كما يقال لها Regex اختصاراً، والتي وفرت علي ساعات طويلة من العمل الشاق! الريجكس هي عبارة عن تعبيرات نمطية تستخدم لوصف النصوص بحيث يمكن مطابقة عدد كبير منها بأقل وصف ممكن. على سبيل المثال، لدي ملف وأريد حذف جميع السطور الفارغة كيف سأفعل ذلك؟ بدون الريجكس غالباً ستحتاج المرور بعينك على كل أجزاء الملف لتستخرج منه السطور وتحذفها يدوياً، لكن عن طريق الريجكس، ستصف السطور التي تريدها وستقوم أداة ما بالبحث في أنحاء الملف واستخراج ما قمت بوصفه. التعبيرات النمطية تختصر عليك وقتاً ومجهوداً هائلاً خصوصاً في المستندات كبيرة الحجم. ويجدر بالذكر أنه يوجد نوعين من التعابير النمطية، الأولى أساسية "Basic" والآخرى موسعة "Extended". سنتعرض سريعاً لبعض أمثلة ريجكس التي تفيد في تهيئة النصوص قبل العمل عليها، وبالطبع إذا أردت التعمق تستطيع القراءة أكثر حول التعبيرات النمطية. أنا شخصياً أفضل كتابة النصوص في ملف نصي بسيط ثم استعمال ليبر أوفيس في التنسيق النهائي، وهذا يعطينا ميزة تطبيق بعض سكربتات باش على هذه الملفات عوضاً عن تنفيذ كل تعبير نمطي على حدة، وذلك باستعمال برنامج sed الذي يأتي تقريباً مع كل توزيعات لينوكس هذه الأيام. ليس هذا فقط؛ بل أيضاً استعمال محرر بسيط أثناء الكتابة يساعدك على التركيز والتخلص من أي تشويش حيث تكون أنت والنصوص فقط. ليبر أوفيس يدعم الريجكس، أيضاً محرر نصوص جنوم الافتراضي جي-إيدت يدعم الريجكس عبر إضافة تسمى Gedit RE Search. حسناً فالنبدأ، في ريجكس:

  • العلامة "^" تعني أول السطر.
  • العلامة "$" تعني آخر السطر.
  • العلامة "|" تعني "أو" ... كذا أو كذا.
  • النقطة "." تعني أي محرف (حرف، رقم، علامة. وهي تقابل "*" في لينوكس شل).
  • العلامة "&" تعني قيمة ناتج البحث. (على سبيل المثال إذا كنا نبحث عن "محمد" وسنستبدلها بـ "&ين" سيظهر الاسم في النهاية "محمدين")
  • العلامة "\<" تعني إذا كان في أول الكلمة، مثلاً التعبير "\<زيد" سيطابق "زيدان" ولن يجد "أبوزيد" .
  • العلامة "\>" مثل سابقه لكن في آخر الكلمة، إذن التعبير "\>زيد" سيطابق "أبوزيد" وليس "زيدان".
  • العلامة "?" تعني يوجد مرة واحدة على الأقل أو لا يوجد تماماً، فعلى سبيل المثال إذا كتبنا "أح?د" سيطابق كلمة "أحمد" وسيطابق أيضاً كلمة "أحد".
  • العلامة "*" تعني لا يوجد أو عدد لا نهائي من المرات.
  • العلامة "+" تعني يوجد مرة واحدة على الأقل أو أكثر من مرة.
  • العلامة "[^ANY]" تعني استبعاد المذكور بعد علامة "^" بمعنى إذا قلنا "[^أحمد]" سيتم مطابقة كل الكلمات عدا كلمة أحمد.
  • العلامة "\t" تعني tab.
  • العلامة "\s" تعني مسافة.
  • العلامة "\S" تعني أي حرف عدا المسافة.
  • العلامة "\n" تعني سطر جديد، أي كأنك ضغطت زر Enter.
  • العلامة "\d" تعني أي رقم.
  • العلامة "\D" تعني أي شيء عدا الأرقام.
  • العلامة "\w" تعني أي كلمة (مكونة من حروف أو أرقام أو علامة "_").
  • العلامة "\W" تعني أي شيء عدا الكلمات (أي الرموز الأخرى).

أخيراً العلامة "\" هي محرف الهروب، بمعنى إذا كنت تقصد نقطة "." فعلاً وليس أي حرف اكتب قبلها الشرطة المائلة هكذا "\." وسيفهم انك تقصد النقطة فعلا وليس شيء آخر. هنا قائمة ببعض الاستخدامات الشائعة على موقع ليبر أوفيس: List of Regular Expressions. هذا أيضاً مرجع آخر: Example regular expressions for Writer. كذلك مرجع مختصر على الموقع Rubular - Regex quick reference.

* * * * * * *

أمثلة؟ (مع ملاحظة وجود بعض الاختلافات الطفيفة بين ليبر أوفيس وإضافة جي-إيدت) في ليبر أوفيس اضغط Ctrl + H سيفتح لك نافذة البحث والاستبدال، اضغط على More Options ثم أشر على Regular expression.

البحث والاستبدال في ليبر أوفيس

◾ نريد على سبيل المثال التخلص من السطور الفارغة، نقوم بعملية بحث واستبدال (Find & Replace) فسنقوم بالبحث على "^$" واستبداله بـ "لاشيء"! ... هكذا سيقوم بحذف أي سطور فارغة. ◾ حذف السطور الفارغة التي تحتوي مسافات فقط:

^[\ ]*$◾ حذف أي عدد من مسافات الفارغة في أول السطر:

^[\ ]*◾ حذف أي مسافات فارغة في نهاية السطر:

[\ ]*$◾ البحث عن أي سطر يبدأ بإحدى هذه الكلمات "فلان" أو "علان" أو "بلتكان".

^(فلان|علان|بلتكان)◾ البحث عن أكثر من كلمة وتطبيق نفس التغييرات عليهم، على سبيل المثال البحث عن "محمد"، "حسن"، "عوض" ونضيف إليهم "ين" في نهاية الكلمة فيصبحوا "محمدين"، "حسنين"، "عوضين":

(محمد|حسن|عوض) وفي خانة الاستبدال نكتب:

&ين

◾ اضافة سطر بعد سطر آخر، بالبحث عن ".$"واستبداله بـ "&\n" (طبعاً يمكن استبدال النقطة التي تدل على أي حرف بشيء محدد أكثر).

◾ البحث عن أي سطر لا ينتهي بنقطة وأيضاً لا ينتهي برمز من الرموز مثل "؟" أو "!" أو "." ... إلخ (طبعاً يمكن تخصيصه بالشكل المناسب، ولاحظ أنه سيتم وضع نقاط حتى في العناوين إذا لم تكن تنتهي برمز من الرموز المذكورة) وذلك عن طريق البحث عن "[^\?\!\.\:\;\؛\?]$" واستبداله بـ "&.".

* * * * * * *

تلميح ١: إذا كنت تريد البحث واستبدال علامات مثل التنوين ستحتاج تفعيل الريجكس وليس استخدام البحث العادي.

تلميح ٢: ًالغ تفعيل الريجكس بعد الانتهاء مما تقوم به حتى لا تجد نفسك قد قمت باستبدال أشياء لا تريدها بالخطأ لاحقا.

تلميح ٣: يمكنك استخدام إضافة لليبر أوفيس عوضاً أداة البحث والاستبدال الافتراضية لتلافي بعض القصور فيها (إذا كنت تريد المزيد من الاستخدامات المتقدمة)، وذلك عبر الإضافة Alternative dialog Find & Replace for Writer.

تلميح ٤: تستطيع عمل شل سكربت (أو حتى سطر واحد شل) باستخدام sed يقوم بكل هذه الأمور مرة واحدة على الملفات النصية قبل البدء في تنسيقها على ليبر أوفيس، واستخدام sed سهل، وهنا بعض صيغه:

sed -i 's/find/replace/g' file.txt هكذا سيقوم بالبحث عن كلمة find ويستبدلها بـ كلمة replace في الملف file.txt صيغة الحذف:

sed -i '/any word/d' filename.txt تستطيع تمرير أكثر من تغيير في المرة الواحدة بالإضافة إلى استعمال التعبيرات النمطية، مثلاً هذا السطر سيقوم بحذف أي مسافات في أول السطر، وأي مسافات في آخر السطر، وأي سطور تحتوي على مسافات فقط ... وبالطبع تستطيع عمل التوليفة التي تحتاجها عبر خيارات سِد المتنوعة.

sed -i 's/^[\ ]*//;s/[\ ]*$//;/^[\ ]*$/d' file.txt

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