Regex لا يعمل في سيرش كونسول؟ كيف تختبره وتصلحه

26 دقيقة تقريبًا

لحد دلوقتي إحنا بقينا نقدر نكتب Regex كويس جدًا — نعزل Brand وNon-brand، نطلع Queries طويلة، نحدد أسئلة ومقارنات وكلمات سعرية، نتعامل مع العربي، ونحلل أقسام كاملة من الموقع. لكن فيه مشكلة أخطر من إن Regex يطلع Error: إن Regex يشتغل عادي جدًا، ويرجعلك نتائج، وأنت تفتكر إنه صح — مع إنه في الحقيقة بيرجع Segment مختلف عن اللي أنت كنت عايزه. وده أخطر بكتير من Error واضح.

أول قاعدة: Regex اشتغل لا تعني Regex صح

أنت عايز Queries مرتبطة بالمقارنة، وكتبت:

(مقارنة|مقابل|الفرق بين|ولا)
  • مقارنة iphone و samsung
  • iphone مقابل samsung
  • الفرق بين macbook air و pro
  • iphone ولا samsung
  • هل الشحن مجاني ولا لا
  • هل الضمان سنة ولا سنتين

أول أربع Queries ممتازة. لكن آخر اتنين؟ فيهم «ولا» — فـRegex نفّذ القاعدة صح، لكن الـSegment نفسه مش بالشكل اللي أنت كنت تقصده. المشكلة مش إن Regex «مكسور»، المشكلة إن القاعدة اللي كتبناها أوسع من السؤال اللي بنحاول نجاوبه.

نوعين من الأخطاء
  1. 1False Positive — نتيجة ظهرت، لكن مش المفروض تكون ضمن المجموعة (مثل «هل الشحن مجاني ولا لا»)
  2. 2False Negative — نتيجة المفروض تدخل، لكنها ما ظهرتش (مثل iphone vs samsung لو Pattern بيقبل vs)
ملحوظة
الشغل الحقيقي هو الموازنة بينهم. لو وسعت Pattern جدًا، هتقلل الـFalse Negatives لكن ممكن تزود الـFalse Positives — والعكس صحيح. مفيش إجابة واحدة، بيعتمد على: أنت بتستخدم الـSegment في إيه؟ Discovery أولي يبدأ أوسع، تقرير أرقام دقيق يحتاج مراجعة أكتر.

متبدأش بالـRegex الكبير

افترض عايز Brand Regex يغطي smart store وsmartstore وسمارت ستور وسمارتستور. الأفضل تبدأ بـ smart store، اختبر، بعدها smart ?store، اختبر، بعدها تضيف العربي، اختبر. كل مرة أنت عارف بالضبط إيه الجزء اللي أضفته، وإيه النتائج الجديدة اللي ظهرت بسببه.

طريقة البناء
  1. 1أبسط Pattern ممكن
  2. 2اختبار
  3. 3إضافة جزء واحد
  4. 4اختبار
  5. 5إضافة جزء واحد
  6. 6اختبار

نفس اللي عملناه في Python: كود صغير، نطبع النتيجة، نفهمها، بعدها نزود.

لازم يكون عندك Test Cases قبل التشغيل

قبل ما تحط Regex في Search Console، اكتب لنفسك أمثلة: إيه اللي لازم يظهر، وإيه اللي لازم ما يظهرش. دلوقتي لما تشغل الـPattern، أنت عندك توقع — مش بتبص للنتائج وتقول «شكلها كويسة». دي زي Unit Tests بسيطة جدًا للـRegex.

خد بالك
متغيرش 5 حاجات مرة واحدة. لو Pattern فيه مشكلة وعدّلت كلمة جديدة وGroup جديدة وAnchor وCharacter Class وOptional space كلهم مع بعض، وبعدين النتيجة اتظبطت — هل عرفت إيه اللي أصلح المشكلة؟ لا. لما Debugging، غيّر حاجة واحدة، اختبر، بعدها التانية.

سؤال Debugging مهم جدًا

كل مرة نتائج زيادة تظهر، اسأل: الـRegex طابق الجزء ده إزاي؟ مثلًا product ظهر في best-product-photography لأن النص موجود داخل الـURL — Search Console يعمل Partial Match افتراضيًا، يعني الـRegex ممكن يطابق أي جزء من النص ما لم تستخدم ^ أو $. لما تسأل «إيه الجزء اللي عمل Match؟» بتوصل للمشكلة أسرع.

مشكلة تانية شائعة: Anchor في المكان الغلط. افترض عايز Query تبدأ بـ «كيف»، لكن كتبت كيف$ بالغلط:

كيف$
  • كيف اختار لابتوب
  • لابتوب كيف

أنت كده بتقول «Query تنتهي بكيف»، مش «تبدأ بكيف». ممكن Regex يشتغل ويرجع نتائج قليلة جدًا، فتفتكر إن الناس مش بتبحث بصيغة «كيف»، بينما المشكلة في Pattern. اقرأ الـRegex بصوت منطقي كل مرة: ^كيف يعني «بداية النص، ثم كيف». كيف$ يعني «كيف، ثم نهاية النص».

أهم سؤال لما تاخد Regex جاهز

ممكن تاخد Pattern من مقال أو Stack Overflow أو ChatGPT أو زميل. متسألش بس «هل بيشتغل؟» اسأل «هو معمول لأي Regex engine؟» — لأن مش كل Regex على الإنترنت هو نفس الـRegex اللي Search Console بيفهمه. Search Console يستخدم RE2. مش محتاج تدخل في تفاصيل البرمجة، كل اللي يهمنا إن فيه أكتر من Regex engine، وفيه Features شغالة في PCRE أو Perl لكن مش مدعومة في RE2.

مثال مهم: Lookahead وLookbehind وBackreferences

ممكن تشوف على الإنترنت حاجة زي دي، ومش مهم دلوقتي نفهم الـPattern بالكامل. المهم تعرف إن الجزء (?=...) اسمه Positive Lookahead، وRE2 لا يدعمه:

iphone(?=.*price)

وكذلك Negative Lookahead (?!...) غير مدعوم:

^(?!.*repair).*iphone.*

ولو لقيت Lookbehind (?<=...) أو (?<!...)، دول برضه غير مدعومين في RE2. ونفس الكلام مع Backreferences زي \1.

خد بالك
هل إحنا محتاجينها في الكورس؟ غالبًا لا. بس لو ChatGPT أو موقع Regex اداك Pattern فيه واحدة من دول، متفترضش إنه هينفع داخل Search Console — حتى لو المتصفح عندك (زي المتصفح اللي بيشغّل الأمثلة في الدرس ده) يقدر يفهمها وتشتغل، لأنه محرك مختلف تمامًا عن RE2.

دي نقطة مهمة في استخدام AI

لو قلت لنموذج AI «اعملّي Regex يجيب Query فيها iphone لكن مش repair»، ممكن النموذج يديك Pattern فيه Negative Lookahead. الحل مش إنك تقول «Regex مش نافع»، الحل إنك تعرف حدود البيئة اللي أنت شغال فيها. الأفضل تكون واضح من الأول:

القاعدة
اكتب Regex متوافق مع Google RE2 لاستخدامه داخل Search Console، وتجنب Lookahead وLookbehind وBackreferences، واشرح كل جزء، واديني 5 حالات يجب أن تطابق و5 حالات يجب ألا تطابق. حتى لو النموذج شرح Pattern كويس، ممكن يكون فهم هدفك غلط أو افترض Variations غير موجودة — AI يساعدك تبني Regex، مش بديل عن مراجعة البيانات الحقيقية.

طيب أعمل Include A لكن Exclude B إزاي من غير Lookahead؟ متحاولش تضغط كل المنطق في Pattern واحد ذكي. في Search Console تقدر تستخدم الفلاتر الموجودة: تعزل iphone بفلتر، وتستبعد repair بفلتر تاني منفصل، أو تعمل التحليل على مراحل.

القاعدة
لو الحل يحتاج Feature غير مدعومة في RE2، متحاولش تخترع Regex أعقد. غيّر طريقة التحليل. مش كل مشكلة لازم تتحل في Regex واحد — أحيانًا Regex صغير + Filter تاني أوضح من Regex ضخم. وكمان متحاولش تستخدم Regex لمقارنة Metrics: عايز Queries عندها Impressions أكتر من 1,000؟ Regex مش الأداة، هو بيطابق نصوص مش أرقام عمودية.

مشكلة: Invalid Regex ومفيش نتائج

جوجل توضح إن بنية Regex غير الصالحة قد ترجع بدون Matches. يعني لو Pattern رجع صفر، متفترضش فورًا «مفيش بيانات». ممكن يكون الـPattern غلط، أو Syntax غير مدعومة، أو Escape ناقص، أو Group مش مقفولة، أو أنت بتبحث عن صيغة مش موجودة فعلًا. لازم تفرق بينهم.

أول خطوة لو النتيجة صفر: بسّط الـPattern
  1. 1iphone — هل فيه نتائج؟
  2. 2(iphone|samsung) — لسه فيه؟
  3. 3(iphone|samsung).*\d — لسه فيه؟
  4. 4^(iphone|samsung).*\d{4}$ — دلوقتي وين توقفت النتائج؟
  5. 5المشكلة بدأت بعد إضافة أي جزء؟ — ده Binary Debugging بسيط

نفس الفكرة مع Pattern طويل زي (?-i)^https://example\.com/(blog|guides)/.*(2025|2026).*\.pdf$: فكّه جزء جزء — (?-i) Case-sensitive، ^https://example\.com/ ابدأ بالدومين، (blog|guides) Blog أو Guides، .* أي شيء بعده، (2025|2026) لازم السنة تظهر، .* أي شيء، \.pdf$ وينتهي بـPDF. لو مش محتاج PDF أصلًا شيل الجزء، لو مش محتاج Case-sensitive شيله — كل جزء في Pattern لازم يكون له سبب.

خد بالك
إياك تعمل Regex «احتياطي»: تحط .* في كل مكان لمجرد إنك شايفها في الأمثلة. Search Console يعمل Partial Match افتراضيًا، فلو عايز «سعر» مش لازم تكتب \.*سعر\.* في أغلب الحالات — استخدم .* لما يكون ليها دور حقيقي داخل Pattern أكبر.

نفهم .* كويس: ترتيب الكلمات

iphone.*price يعني «iphone، وبعدها في أي مكان لاحق price» — بالترتيب ده تحديدًا.

توقّع النتيجة

كام Query من الاتنين هتتطابق مع iphone.*price؟ (فكر في الترتيب)

iphone.*price
  • iphone 17 price
  • price iphone 17

.* لا يعني «الكلمتين بأي ترتيب»، هو يسمح بوجود Characters بين جزأين بالترتيب اللي أنت كتبته. لو محتاج الاتجاهين: (iphone.*price|price.*iphone). لكن اسأل نفسك: هل أنا محتاج ده أصلًا؟ يمكن Price Segment البسيط (سعر|اسعار|تكلفة|بكام) ومراجعة Queries الخاصة بصفحة معينة تكون أبسط.

خطأ تاني: Character Class مش Group

اتكلمنا عنها في درس العربي، لكن دي من أكتر أخطاء الـDebugging شيوعًا. عايز «سعر أو تكلفة» وكتبت [سعر|تكلفة] بالغلط:

[سعر|تكلفة]
  • سعر ايفون
  • تكلفة ايفون
  • شراء ايفون
  • لابتوب
خد بالك
لاحظ إن «لابتوب» طابقت برضه! لأن [سعر|تكلفة] معناها «حرف واحد من: س ع ر | ت ك ل ف ة»، وكلمة «لابتوب» فيها حرف «ل» اللي هو ضمن المجموعة دي. [] تختار Character واحد، مش كلمة. الصحيح (سعر|تكلفة).
(سعر|تكلفة)
  • سعر ايفون
  • تكلفة ايفون
  • شراء ايفون
  • لابتوب

خطأ تاني: ? راجعة على إيه بالظبط؟ في smart ?store الـ? راجعة على المسافة اللي قبلها. لكن لو كتبت smart store? الـ? راجعة على الـe الأخيرة — Pattern مختلف تمامًا. لذلك لما تشوف Quantifier زي ? أو + أو * أو {n}، اسأل: هو بيتطبق على إيه بالضبط؟

Bug مقابل Limitation

ملحوظة
Bug: Pattern لا يعمل بالشكل اللي أنت صممته له — زي product بدل ^https://example.com/product/ لما هدفك Structure محددة. Limitation: Pattern يعمل كما صممته، لكن الطريقة نفسها لها حدود — زي ^\S+(\s+\S+){6,}$ اللي بيعتمد على المسافات فمش هيفصل iphone-17-pro-max لكلمات منفصلة. ده مش Bug، ده Design معروف. لو فاهم الفرق، هتعرف إمتى تصلح Regex وإمتى تغير طريقة التحليل.
جرّب بنفسك

عندك: (سعر|تكلفة|ثمن|بكام) ضد سعر ايفون، تكلفة ايفون، ثمن ايفون، ايفون بكام، اسعار ايفون. إيه الـFalse Negative؟

  • سعر ايفون
  • تكلفة ايفون
  • ثمن ايفون
  • ايفون بكام
  • اسعار ايفون

اسعار ايفون هي False Negative — الحل: [اأ]سعار بدل سعار بس.

الاختبار التطبيقي

عندك: مقارنة iphone و samsung، iphone مقابل samsung، الفرق بين macbook air و pro، iphone vs samsung، هل الشحن مجاني ولا لا، هل الضمان سنة ولا سنتين، أفضل iphone، سعر iphone.

تحدّي Regex

Comparison Segment من غير False Positives

ابني Comparison Regex يغطي الحالات الأساسية للمقارنة، من غير ما يجيب «هل الشحن مجاني ولا لا» أو «هل الضمان سنة ولا سنتين» كنتائج زيادة.

لازم يظهر
  • · مقارنة iphone و samsung
  • · iphone مقابل samsung
  • · الفرق بين macbook air و pro
  • · iphone vs samsung
لازم ما يظهرش
  • · هل الشحن مجاني ولا لا
  • · هل الضمان سنة ولا سنتين
  • · أفضل iphone
  • · سعر iphone

اختبار التفكير

أنا مش مهتم بعد الدرس إنك تحفظ «Lookahead مش مدعوم، Lookbehind مش مدعوم». دي معلومات مهمة، لكن مش الهدف. الهدف إنك أول ما تاخد Regex جديد تسأل: أنا فاهم كل جزء فيه؟ هو متوافق مع RE2؟ إيه اللي أتوقع يظهر؟ إيه اللي أتوقع ما يظهرش؟ إيه الـFalse Positives؟ إيه الـFalse Negatives؟ هل Pattern غلط ولا طريقة التحليل نفسها محدودة؟ لو عملت كده، أنت مبقتش شخص بينسخ Regex، أنت بقيت قادر تبنيه، تختبره، وتصلحه.

قبل الدرس التالي

إحنا تقريبًا خلصنا الأدوات اللي محتاجينها داخل الكورس. الخطوة اللي جاية مش محتاجة Symbols كتير جديدة — هي الأهم: إزاي تجمع كل ده وتحوّل Regex من فلتر إلى تحليل SEO كامل. يعني هنبدأ بسؤال، نبني Segment، نراجع صحته، نقرأ Clicks وImpressions وCTR وPosition والتغير مع الوقت، وبعدها نسأل: إيه القرار أو التحقيق اللي المفروض يطلع من البيانات؟ وده هيكون الدرس الأخير قبل المشروع النهائي.

أحسنت، وصلت إلى نهاية الدرس.