التعبير النمطي Regular Expression (أو Regex) هو متتالية من المحارف يمكننا استخدامها لاستهداف عناصر معينة في السلاسل النصية والتلاعب بها. وبهذا يمكننا:
💡 صيغة التعبيرات النمطية في JavaScript جزء من معيار ECMA-262 الخاص باللغة. هذا يعني أنك لا تحتاج إلى القلق بشأن التوافق مع متصفح بعينه.
في JavaScript، تُكتب التعبيرات النمطية غالبًا بالصيغة /pattern/modifiers.
ولدينا طريقتان لإنشاء تعبير نمطي:
const regex = /[a-z]/;
const regex = new RegExp('[a-z]');
في كلتا الحالتين، تُنشئ JavaScript كائنًا من التعبير النمطي. ويُوصى باستخدام أنماط غير قابلة للتغيير مع اعتماد الصيغة الحرفية كخيار افتراضي.
يمكن استخدام البانية RegExp في الحالات التي سيتغير فيها التعبير النمطي أو التي لا نعرفه فيها بعد (مثل مُدخل).
تمتلك التعبيرات النمطية قوى خارقة اختيارية تُسمى flags تتيح ميزات إضافية.
ومن أكثرها استخدامًا:
/g - البحث الشامل/i - تجاهل حالة الأحرف/m - البحث متعدد الأسطروإليك مثالًا بسيطًا:
const re = /home/gi;
const str = 'Home, sweet home.';
const myArray = str.match(re);
console.log(myArray);
=> // ["Home", "home"]
يسمح لنا المحرف g بتحليل جميع المطابقات الممكنة داخل السلسلة النصية. فبدون هذه الميزة، كانت JavaScript ستستخرج أول تطابق Home فقط.
يتيح لنا علم تجاهل حالة الأحرف /i مرونة أكبر عند البحث عن نمط. وبذلك لا يهم إن كان ما نبحث عنه بحروف UPPERCASE أو lowercase.
عند استخدام البانية RegExp، تختلف صيغة إضافة الأعلام.
let regex = /[a-z]/gi; // literal notation
let regex = new RegExp('[a-z]', 'gi'); // constructor with string pattern as first argument
let regex = new RegExp(/[a-z]/, 'gi'); // constructor with regular expression literal as first argument (Starting with ECMAScript 6)
عندما تُدمج التعبيرات النمطية مع الدوال المدمجة الحالية في JavaScript، نحصل على أساليب قوية للتلاعب بالبيانات واستخراجها من السلاسل النصية.
هذه بعض الدوال الأكثر شيوعًا التي تُستخدم إلى جانب التعبيرات النمطية.
تُنفّذ الطريقة test() بحثًا عن تطابق بين تعبير نمطي وسلسلة نصية محددة. وتُرجع صحيحًا أو خطأ.
const str = 'It is difficult to test if you have a virus';
const result = /virus$/.test(str);
console.log(result);
// => true
باستخدام الطريقة match()، نحصل على مصفوفة مفيدة يعتمد محتواها على وجود المطابقات التي وُجدت أو غيابها.
وبهذا نستطيع أن نبحث ونستخرج معلومات من أي سلسلة نصية. على سبيل المثال:
const funnyQuote =
'If you see someone crying, ask if it is because of their haircut.';
const regex1 = /someone/;
const regex2 = /happy/;
funnyQuote.match(regex1);
// => ["someone", index: 11, input: "If you see someone crying, ask if it is because of their haircut.", groups: undefined]
funnyQuote.match(regex2);
// => null
عند وجود علم البحث الشامل /g، بدلًا من الحصول على المطابقة الوحيدة مع معلومات مفيدة مثل الفهرس أو المُدخل، تُرجع الطريقة جميع الحالات الظاهرة في المصفوفة:
const funnyQuote =
'If you see someone crying, ask if it is because of their haircut.';
const regex3 = /if/gi;
funnyQuote.match(regex3);
// => ["If", "if"];
تتيح لنا الطريقة replace() في JavaScript البحث عن قيمة داخل سلسلة نصية معينة واستبدالها بقيمة جديدة مرغوبة.
string.replace(searchValue, newValue);
يمكن أن يكون النمط المستخدم في البحث والاستبدال سلسلة نصية واحدة أو تعبيرًا نمطيًا.
let string = 'I like dogs!';
let result = string.replace('dogs', 'cats');
let string = 'I would love to travel to Japan';
let result = string.replace(/Japan/g, 'Hawaii');
علاوة على ذلك، يمكننا تمرير دالة في موضع الاستبدال لإجراء تغييرات إضافية على كل قيمة.
let text = 'Say hello to the chatbot.';
let result = text.replace(/chatbot|hello/gi, function (word) {
return word.toUpperCase();
});
// => "Say HELLO to the CHATBOT"
تمثّل الطريقة split() في JavaScript أسلوبًا مختلفًا لاستخدام السلاسل النصية والتلاعب بها باستخدام التعبيرات النمطية.
وبهذا، سنستخدم التعبير النمطي لتقسيم سلسلة نصية معينة عبر التعرف على نمط، مثل str.split(/[,.\s]/). وسيُستخدم هذا النمط كـ separator.
const str = 'hello,user.how are.you';
const result = str.split(/[,.\s]/);
console.log(result);
// => ['hello', 'user', 'how', 'are', 'you']
لقد تم تعيينك أخصائي تعابير نمطية في شركة تطوّر روبوت دردشة.
الشركة في مرحلة تطوير أولية جدًا، لذلك مهمتك هي استخدام التعابير النمطية لتحسين قدرة روبوت الدردشة على فهم اللغة الطبيعية وتوليدها.
بالإضافة إلى كونه ذكيًا، فإن روبوت الدردشة مساعد وفيّ.
لكي يسأل المستخدم روبوت الدردشة عن شيء ما، عليه أن يذكر كلمة “Chatbot” في الموضع الأول من الأمر.
لا يهم إن كانت الكلمة المفتاحية بأحرف كبيرة أو صغيرة. المهم هنا هو موضع الكلمة.
نفّذ الدالة isValidCommand() التي تساعد روبوت الدردشة على التعرّف على وقت إعطاء المستخدم أمرًا.
isValidCommand("Chatbot, play a song from the 80's.";
// => True
isValidCommand("Hey Chatbot, where is the closest pharmacy?";
// => False
isValidCommand("CHATBOT, do you have a solution for this challenge?";
// => True
يجد روبوت الدردشة صعوبة في فهم كيفية استخدام البشر للرموز التعبيرية للتعبير عن مشاعرهم.
عندما يتلقى روبوت الدردشة رسائل المستخدم، يُمثَّل كل رمز تعبيري بالكلمة emoji متبوعة برقم id الخاص به.
نفّذ الطريقة removeEmoji() لتأخذ سلسلة نصية وتزيل تشفير الرموز التعبيرية كله في الرسالة.
تُرجع الأسطر التي لا تحتوي على نص الرموز التعبيرية دون تعديل.
اكتفِ بإزالة نص الرموز التعبيرية. لا تحاول تعديل المسافات البيضاء.
في هذا التحدي تحديدًا، استخدم صيغة الدالة البانية لإنشاء التعبير النمطي.
removeEmoji("I love playing videogames emoji3465 it's one of my hobbies");
// => "I love playing videogames it's one of my hobbies"
بالنظر إلى إمكانية تنزيل ميزات روبوت الدردشة على تطبيق جوال، يُتوقع من المستخدم كتابة رقم هاتف أثناء المحادثة.
المشكلة أن روبوت الدردشة لا يستطيع قراءة والتحقق إلا من رقم بصيغة محدّدة.
إذا كان الرقم صالحًا (يطابق تسلسل المحارف الذي يحدده التعبير النمطي)، يجيب روبوت الدردشة برسالة يشكر فيها المستخدم ويؤكد الرقم. وإذا كان الرقم غير صالح، تخبر الدالة المستخدم بأن رقم الهاتف غير صالح.
الصيغة المتوقعة هي: (+##) ###-###-###
checkPhoneNumber('(+34) 659-771-594');
// => "Thanks! You can now download me to your phone."
checkPhoneNumber('659-771-594');
// => "Oops, it seems like I can't reach out to 659-771-594"
روبوت الدردشة برنامج فضولي جدًا. فرغم أنه يستطيع البحث في الإنترنت عن موضوع معيّن، إلا أنه يحب أن يسأل المستخدمين عن مواقع أو روابط رائعة ليجد معلومات ذات صلة.
مثال على محادثة:
نفّذ الدالة getURL() القادرة على إرجاع مصفوفة تحتوي على رابط كل موقع فقط. إن كتابة تعبير نمطي للتعرّف على أي رابط أمر معقّد جدًا، لكن روبوت الدردشة يحتاج فقط إلى قراءة روابط بسيطة. في هذا التمرين، الرابط هو أي تسلسل من الكلمات مفصولة بـ ".".
getURL(
'I learned a lot from exercism.org and developer.mozilla.org, but I found ts39.es very boring!',
);
// => ["exercism.org", "developer.mozilla.org", "ts39.es"];
لتخزين بيانات كل الأشخاص الذين أجروا محادثة معه، يستطيع روبوت الدردشة الحصول على الاسم الكامل من ملف تعريف المستخدم بهذا الشكل: “smith, john”.
بهذه الطريقة، نريد أن يكون روبوت الدردشة لطيفًا جدًا وأن يترك انطباعًا جيدًا.
اكتب الدالة niceToMeetYou() التي تأخذ سلسلة نصية تحتوي على الاسم الكامل للمستخدم، وتُرجع السلسلة النصية “Nice to meet you, John Smith”
لأغراض التعلّم، نفّذ الدالة باستخدام طريقة الاستبدال من التعابير النمطية.
let str = 'Smith, John';
niceToMeetYou(str);
// => "Nice to meet you, John Smith"
سجّل في Exercism لتتعلّم وتتقن JavaScript عبر 37 مفهومًا159 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.