Regex مع الكلمات العربية: اختلافات الكتابة وحدود الكلمات

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

في الدروس اللي فاتت كنا بنستخدم العربي عادي داخل Regex — كتبنا مثلًا (سعر|تكلفة|ثمن) واستخدمنا ^(كيف|هل|لماذا). لكن المشكلة بتبدأ لما نبص على بيانات Search Console الحقيقية، ممكن تلاقي «اسعار ايفون» و«أسعار ايفون» و«ايفون 17» و«آيفون 17». يعني نفس الشيء اللي بتحاول تعزله، المستخدمين ممكن يكتبوه بأكتر من شكل. النهاردة مش هنتعلم Regex عربي مختلف — نفس Regex اللي اتعلمناه — لكن هنتعلم إزاي نستخدمه مع طبيعة الكتابة العربية من غير ما نحول كل Pattern إلى قائمة ضخمة من الاحتمالات.

الأقواس المربعة []

عندنا: اسعار ايفون، أسعار ايفون، تكلفة ايفون، سعر ايفون. الفرق بين «اسعار» و«أسعار» حرف واحد فقط (ا مقابل أ). هل لازم كل مرة أكتب الكلمتين كاملين؟ لا. لما نكتب [اأ] المعنى: اختار Character واحد من الموجودين داخل الأقواس. فممكن نكتب [اأ]سعار بدل (اسعار|أسعار).

[اأ]سعار
  • اسعار ايفون
  • أسعار ايفون
  • تكلفة ايفون
  • سعر ايفون
خد بالك
[اأ] مختلفة تمامًا عن (ا|أ). في المثال البسيط ده ممكن يوصلوا لنفس النتيجة، لكن [] مخصصة لاختيار Character واحد من مجموعة Characters — مش كلمة. بص على [سعر|تكلفة]: ده غلط لو أنت تقصد "سعر أو تكلفة"، لأن [] تختار حرف واحد، مش كلمة. الصحيح (سعر|تكلفة).

عندنا في العربي أشكال أكتر للألف: ا، أ، إ، آ. لو محتاجين نغطي الأربعة: [اأإآ]يفون. هل كل الأربع طرق صحيحة لغويًا؟ مش ده السؤال — إحنا بنتعامل مع Queries حقيقية يكتبها المستخدمون.

[اأآ]يفون
  • ايفون 17
  • آيفون 17
  • أيفون 17
  • سامسونج s26
القاعدة
متعملش Normalization لمجرد إنك تقدر. متقولش «من النهاردة كل ألف أكتبها [اأإآ]». استخدمها لما يكون عندك سبب — يعني لقيت في Search Console فعلًا Variation حقيقي. لو مفيش Variation حقيقي في البيانات، متزودش تعقيد من غير داعي. نفس القاعدة من أول الكورس: أبسط Pattern يحل المشكلة.

نفس الفكرة مع ي وى ([يى]) ومع ة وه — مثلًا شرك[ةه] تطابق «شركة» و«شركه». لكن خلي بالك: إحنا مش بنعمل تصحيح لغوي، ولا بنقول «كل ة = ه» بشكل عام. إحنا بنستخدم Character Class في مكان محدد داخل كلمة محددة لأننا لاحظنا Variation حقيقي.

ملحوظة
دي أهم عقلية في Regex العربي: إحنا مش بنحاول نخلي Regex يفهم اللغة العربية. إحنا بنقوله: في المكان ده تحديدًا، عندي أكتر من Character ممكن يظهر.

() مقابل []

لو عندي كلمات كاملة (سعر، تكلفة، ثمن) أستخدم (سعر|تكلفة|ثمن). لو عندي Character مختلف في نفس المكان (اسعار، أسعار) أستخدم [اأ]سعار. نقدر نجمعهم: (سعر|[اأ]سعار|تكلفة|ثمن) — مجموعة من الكلمات، وجوا واحدة منهم استخدمنا Character Class لاختيار شكل الحرف.

دلوقتي نحاول نطابق الكلمة الكاملة

افترض عايز كلمة «سعر» نفسها، مش النص موجود داخل كلمة أطول. في شروحات Regex الإنجليزية هتلاقي ناس تستخدم \bprice\b وتفكر «أعمل نفس الحاجة» فتكتب \bسعر\b. هنا عندنا مشكلة حقيقية.

محرك RE2 اللي بيستخدمه Search Console يعرف \w على إنه فقط A-Z وa-z و0-9 و_ — Characters من ASCII. والـ \b بيعتمد على حدود \w دي. الحروف العربية نفسها مش داخلة في \w. نجرب \bسعر\b فعليًا:

\bسعر\b
  • سعر
  • سعر ايفون
  • كم سعر ايفون
  • اعرف سعر
  • الاسعار اليوم
خد بالك
لاحظ: ولا صف واحد اتعلّم، حتى «سعر» المجردة و«سعر ايفون» اللي المفروض تظهر بالتأكيد. لأن الحروف العربية مش Word Characters بالنسبة لتعريف \w، فـ \b مبيلاقيش حدود أصلًا حوالين أي كلمة عربية. نقل Pattern زي \bprice\b إلى \bسعر\b مش طريقة صح نفترض إنها هتشتغل بنفس السلوك.

طب أعمل إيه لو عايز كلمة عربية كاملة؟ لو بياناتنا مبنية على كلمات مفصولة بمسافات، نقدر نفكر بطريقة إحنا عارفينها أصلًا: عايز «سعر» تكون في بداية الـQuery أو قبلها مسافة، وبعده مسافة أو نهاية الـQuery.

(^|\s)سعر(\s|$)
  • سعر
  • سعر ايفون
  • كم سعر ايفون
  • اعرف سعر
  • الاسعار اليوم

دلوقتي كل الحالات الصح ظهرت، و«الاسعار اليوم» ما ظهرتش لأن «سعر» مش موجودة فيها كجزء منفصل بنفس الشكل. لكن خلي بالك: لو Query فيها «ما سعر؟» — الكلمة بعدها علامة استفهام، مش مسافة ولا نهاية النص مباشرة، فالـPattern البسيط ده ممكن ما يغطيهاش. ابدأ بالبسيط، راجع النتائج، وبعدها وسّع حسب البيانات — مثلًا باستخدام Character Class زي [\s؟،] لو علامات الترقيم دي مهمة في تحليلك.

أعرف هل الـQuery فيها عربي

محرك RE2 بيدعم Unicode character classes، ومن ضمن الـScripts المدعومة Arabic. ممكن نستخدم \p{Arabic} علشان نقول: عندي Character واحد على الأقل من Arabic Script.

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

عندنا \p{Arabic} — كام Query من الأربعة دول فيها Character عربي واحد على الأقل؟

\p{Arabic}
  • iphone price
  • سعر ايفون
  • iphone سعر مصر
  • macbook pro
ملحوظة
خلي بالك من المعنى: \p{Arabic} مش معناه «Query عربية بالكامل»، معناه «Query تحتوي Character عربي واحد على الأقل». يعني «iphone سعر مصر» هتدخل، وده مفيد لو هدفك اكتشاف Queries اللي فيها عربي عمومًا.

طب لو عايز أعرف Queries فيها حروف إنجليزية؟ [A-Za-z] — Character من A إلى Z أو a إلى z.

طب Queries المختلطة عربي وإنجليزي؟

دي حالة مهمة في المواقع العربية — Queries زي «سعر iphone 17» أو «seo في السعودية». عايز Query فيها عربي وإنجليزي في نفس الوقت. الأول لازم نتعلم حاجة صغيرة: الرمز * يعني صفر أو أكثر (مقابل + اللي معناه مرة أو أكثر). ومع . نقدر نكتب .* يعني «أي عدد من الـCharacters، حتى لو صفر».

العربي أولًا ثم الإنجليزي: \p{Arabic}.*[A-Za-z]. الإنجليزي أولًا ثم العربي: [A-Za-z].*\p{Arabic}. نجمعهم:

(\p{Arabic}.*[A-Za-z]|[A-Za-z].*\p{Arabic})
  • iphone price egypt
  • سعر ايفون في مصر
  • سعر iphone في مصر
  • macbook مناسب للطلاب
  • أفضل لابتوب

وده مفيد لما تحاول تفهم سلوك الكتابة: هل الناس بتدمج اسم المنتج بالإنجليزي مع باقي السؤال بالعربي؟ هل البراند بيُكتب بالعربي ولا الإنجليزي؟ هل فيه فرق في CTR بين Queries عربية بالكامل وQueries مختلطة؟

هل لازم أحوّل كل الاختلافات العربية لـRegex ذكي؟

لا. لو بدأت تحاول تختصر كل حرف وكل Variation وكل خطأ إملائي، ممكن تعمل Pattern محدش فاهمه. أحيانًا (تك زون|تيك زون|تكزون|تيكزون) أوضح وأأمن من Regex ذكي جدًا. المعيار مش «مين كتب Regex أقصر؟»، المعيار «هل Pattern واضح ويطلع Segment صح؟»

خد بالك
لو اسم البراند الصحيح "العالمي" لكن المستخدمين بيكتبوا "العالمى"، مش دورك تقول "دي كتابة غلط، مش هحسبها". إحنا بنحلل Search Behavior — لو الناس بتكتبها، فهي جزء من البيانات. لكن نفس القاعدة برضه: متخمنش الأخطاء، ابدأ بما تعرفه، راجع Search Console، شوف Variations الحقيقية، وبعدين أضفها.
جرّب بنفسك

عندك: ايفون 17، آيفون 17، أيفون 17، سامسونج s26. عايز كل Variations الخاصة بكلمة ايفون فقط.

  • ايفون 17
  • آيفون 17
  • أيفون 17
  • سامسونج s26
جرّب بنفسك

عندك: شركة شحن، شركه شحن، أفضل شركة شحن. لو هدفك في الحالة دي فقط تغطية الطريقتين (شركة وشركه)، اكتب Pattern.

  • شركة شحن
  • شركه شحن
  • أفضل شركة شحن

افتكر: ده Pattern لهذه الكلمة، مش قاعدة عامة لتحويل كل ة إلى ه.

جرّب بنفسك

عندك: smart shop، smartshop، سمارت شوب، سمارت شاب. ابني Brand Pattern.

  • smart shop
  • smartshop
  • سمارت شوب
  • سمارت شاب

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

عندك براند اسمه Smart Store، والمستخدمين بيكتبوه: smart store، smartstore، سمارت ستور، سمارتستور.

تحدّي Regex

Brand Regex لـ Smart Store

ابني Pattern يغطي الأربع صيغ، ويستبعد أي Query تانية.

لازم يظهر
  • · smart store
  • · smartstore
  • · سمارت ستور
  • · سمارتستور
لازم ما يظهرش
  • · ايفون 17
  • · سعر ايفون

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

لو عندك Brand عربي، والناس بتكتبه بـ8 طرق مختلفة، إيه أول حاجة تعملها؟ مش «أكتب أذكى Regex ممكن»، لكن «أفهم الاختلافات الحقيقية الموجودة في البيانات». بعدها تقرر: هل الاختلاف Character واحد؟ استخدم []. هل عندي كلمات أو صيغ مختلفة؟ استخدم (). هل جزء صغير اختياري؟ ممكن ?. المهم إن Segment يكون مفهوم وصحيح.

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

لحد هنا إحنا اشتغلنا تقريبًا بشكل أساسي على Queries. لكن Search Console بيسمح لنا نستخدم Regex على Pages برضه. في الدرس التالي هننقل نفس العقلية إلى بنية الموقع. هنشوف إزاي نعزل Blog وProducts وCategories وServices واللغات المختلفة وملفات PDF وPagination وURLs اللي فيها Parameters أو سنوات أو IDs. وهنا Regex هيبدأ يساعدنا مش بس نفهم الناس بتبحث إزاي، لكن كمان نفهم أي أجزاء من الموقع بتحصل على الظهور والزيارات داخل Search Console.

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