سلام! سارا بحرانی هستم. اگه تو هم تا حالا موقع کار با عبارات باقاعده (Regex) با میانبرهایی مثل w و W گیج شدی و دقیقاً ندونستی کی و کجا باید ازشون استفاده کنی، خیالت راحت باشه، تو تنها نیستی!
این دوتا، یعنی w (کاراکتر کلمه) و W (کاراکتر غیر-کلمه)، از مهمترین و پایهایترین ابزارهای تو در دنیای رجکس هستن. درک تفاوت این دو، نه تنها برای اعتبارسنجی فرمها، که برای پاکسازی دادهها و حتی جستجوی دقیق در گوگل آنالیتیکس یا سرچ کنسول حیاتیه.
این دو میانبر، بخشی از چیزی هستن که بهشون میگیم «کلاس های کاراکتری» (Character Classes)؛ یعنی گروههایی از کاراکترها که ما اونها رو با یه کد کوتاه صدا میزنیم.
توی این راهنمای کامل، قراره یک بار برای همیشه بهت نشون بدم که تفاوت w و W دقیقاً چیه، چطور ازشون برای اعتبارسنجی و جداسازی متن استفاده کنی و چطور با درک این دو، روی b (مرز کلمه) مسلط بشی. بیا شروع کنیم!
جدول کاربردی: راهنمای تقلب (Cheat Sheet) سریع
این جدول رو بذار دم دستت. این خلاصهی همهچیزیه که در ادامه قراره یاد بگیری:
| میانبر (Shorthand) | معنی دقیق (ASCII) | چی رو تطبیق میده؟ (مثال) | کاربرد اصلی |
|---|---|---|---|
| w (کوچک) | [A-Za-z0-9_] | حروف، اعداد، آندرلاین (sara, vazir123, _seo) | پیدا کردن و اعتبارسنجی کلمات و شناسهها |
| W (بزرگ) | [^A-Za-z0-9_] | فاصله، علائم نگارشی، نمادها ( , !, #, ?) | پاکسازی و جداسازی (Split کردن) متن |
w چیست؟ (میانبر کلاس کاراکتر کلمه)
بذار خیلی ساده شروع کنیم. وقتی داری با «عبارات باقاعده» یا همون Regex کار میکنی (که مثلاً توی سرچ کنسول، گوگل آنالیتیکس یا حتی برای تنظیم ریدایرکتها و اعتبارسنجی فرمها به کارت میاد)، یه سری میانبر (Shorthand) داری که کارت رو فوقالعاده راحت میکنن.
w یکی از معروفترین و پرکاربردترینِ این میانبرهایه.
به جای اینکه بیای کلی کاراکتر مختلف رو جدا جدا بنویسی، فقط از w استفاده میکنی. معنی این میانبر، «کلاس کاراکتر کلمه» (Word Character Class) هست. یعنی هر کاراکتری که توی یه «کلمه» معمولی پیدا میشه.
تعریف کلاسیک (ASCII): w به عنوان معادل [A-Za-z0-9_]
حالا بیایم دقیقتر بشیم. اگه بخوایم w رو به زبان فنی و کلاسیک (مخصوصاً تو موتورهای رجکسی که فقط بر مبنای استاندارد ASCII کار میکنن) تعریف کنیم، این میانبر دقیقاً مساوی و معادل عبارت [A-Za-z0-9_] هست.
این عبارت یکم طولانی به نظر میرسه، ولی معنیش خیلی ساده است. w دقیقاً با این موارد تطبیق پیدا میکنه:
حروف انگلیسی بزرگ: از A تا Z
حروف انگلیسی کوچک: از a تا z
اعداد (ارقام): از تا 9
کاراکتر آندرلاین: _
پس وقتی تو مینویسی w، انگار به موتور رجکس گفتی: «دنبال هر کاراکتری بگرد که یا حرف انگلیسیه (بزرگ یا کوچیک)، یا عدده، یا آندرلاینه.»
نکته تخصصی (یونیکد): این رو هم به عنوان یه متخصص باید بدونی: توی موتورهای رجکس مدرنتر که از یونیکد (Unicode) پشتیبانی میکنن (مثل پایتون ۳، جاوااسکریپت مدرن و… )، w خیلی قویتر و باهوشتر عمل میکنه! اونجا میتونه حروف زبانهای دیگه مثل «س» یا «ل» در «سلام» (فارسی) یا حروف مشابه در زبانهای دیگه رو هم پیدا کنه. اما تعریف کلاسیک و پایهای که ۹۰٪ مواقع باهاش کار داری، همون معادل ASCII هست که بالا گفتم.
چرا آندرلاین (_) بخشی از «کاراکتر کلمه» محسوب میشود؟ (دلیل تاریخی)
این یه سوال عالی و خیلی منطقیه! شاید با خودت بگی آندرلاین (_) که واقعاً یه «حرف» نیست و ما موقع نوشتن معمولی ازش استفاده نمیکنیم، پس چرا جزو «کاراکتر کلمه» (Word Character) حساب میشه؟
جوابش کاملاً به «تاریخچه برنامهنویسی» برمیگرده.
w (و کلاً مفهوم عبارات باقاعده) از اول برای کار با کد منبع (Source Code) زبانهای برنامهنویسی مثل C و Perl طراحی شده بود. توی این زبانها (و تقریباً تمام زبانهای امروزی)، تو چطور یه متغیر (Variable) یا اسم یه تابع (Function) رو تعریف میکنی؟
نمیتونی از فاصله (Space) استفاده کنی (مثلاً my var غلطه و خطا میده).
نمیتونی از خط تیره (Hyphen) استفاده کنی، چون اون برای عمل تفریق (-) رزرو شده.
برنامهنویسها برای اینکه بتونن اسمهای چند قسمتی و خوانا برای متغیرهاشون بسازن، از آندرلاین استفاده میکردن. مثلاً: user_name یا first_login یا total_count.
چون آندرلاین یه بخش اساسی و جدانشدنی از «کلمهها» توی دنیای کدنویسی بود، خالقین Regex هم تصمیم گرفتن _ رو به عنوان یه کاراکتر کلمهای بپذیرن و اون رو داخل میانبر w جا بدن. اینطوری پیدا کردن اسم متغیرها و توابع توی سورس کدها با رجکس خیلی راحتتر شد.
W چیست؟ (میانبر کلاس کاراکتر غیر-کلمه)
توی دنیای رجکس، خیلی از میانبرها یه نسخه «معکوس» هم دارن که با حرف بزرگ انگلیسی نوشته میشه. W دقیقاً نقطه مقابل w هست.
W (با W بزرگ) یه میانبر برای «کلاس کاراکتر غیر-کلمه» (Non-Word Character Class) هست. یعنی دقیقاً دنبال هر چیزی میگرده که «کلمه» محسوب نشه.
تعریف دقیق: W به عنوان معادل [^A-Za-z0-9_]
یادت میاد که w معادل [A-Za-z0-9_] بود؟ حالا به این عبارت نگاه کن: [^A-Za-z0-9_]
اون علامت ^ (کلاه یا هشتک) وقتی داخل یک براکت [] قرار میگیره، معنیش کاملاً عوض میشه و نقش «نفی کردن» یا «NOT» رو بازی میکنه.
پس W که معادل [^A-Za-z0-9_] هست، به موتور رجکس میگه: «دنبال هر کاراکتری بگرد که جزو این لیست نباشه:»
حرف انگلیسی بزرگ (A-Z) نباشه
حرف انگلیسی کوچک (a-z) نباشه
عدد (0-9) نباشه
و آندرلاین (_) هم نباشه
به عبارت دیگه، W هر چیزی غیر از حروف الفبا، اعداد و آندرلاین رو پیدا میکنه.
W چه چیزهایی را تطبیق میدهد؟
خب، اگه حروف و اعداد و آندرلاین رو کنار بذاریم، چی باقی میمونه؟ دقیقاً همون چیزهایی که W عاشقشونه و اونها رو تطبیق میده:
علائم نگارشی: مثل نقطه (.)، کاما (,)، علامت تعجب (!)، علامت سوال (?)، دو نقطه (:)، خط تیره (-) و…
فاصلهها (Whitespace): شامل خودِ فاصله یا Space ( )، تب (Tab)، و حتی رفتن به خط جدید (Newline).
نمادهای خاص: مثل علامت دلار ($)، امپرسند (&)، هشتگ (#)، درصد (%)، ات ساین (@) و هر نماد دیگهای که فکرش رو بکنی.
رابطه معکوس: W دقیقاً هر چیزی است که w نیست
این مهمترین نکتهایه که باید یادت بمونه. w و W دو روی یک سکه هستن و همدیگه رو کامل میکنن.
w (کوچک): دنبال «کلمه» میگرده.
W (بزرگ): دنبال «هرچیزی به جز کلمه» میگرده.
این دوتا با هم، کل صفحه کلید (و حتی فراتر از اون) رو پوشش میدن. هر کاراکتری که توی متن تو وجود داره، یا توسط w پیدا میشه یا توسط W. امکان نداره کاراکتری باشه که نه این باشه و نه اون.
این ویژگی کجا به دردت میخوره؟ مثلاً وقتی میخوای یه جمله رو بر اساس «کلمهها» جدا کنی. کافیه به رجکس بگی که متن رو بر اساس W (یعنی فاصلهها، نقطهها و…) برات تیکه تیکه کنه.
کاربردهای عملی w: اعتبارسنجی و استخراج
در عمل، ما از w برای دو کار اصلی استفاده میکنیم:
اعتبارسنجی (Validation): یعنی چک کنیم که آیا یه رشته (مثل نام کاربری) فقط شامل کاراکترهای مجاز هست یا نه.
استخراج (Extraction): یعنی کلمهها یا شناسههای خاصی رو از دل یه متن شلوغ بیرون بکشیم.
بریم با چند مثال کلاسیک اینها رو ببینیم.
مثال کلاسیک: اعتبارسنجی نام کاربری (Username Validation)
این یکی از رایجترین و واضحترین کاربردهای w هست. تا حالا موقع ثبتنام توی یه سایت دیدی که بهت میگه: «نام کاربری فقط میتواند شامل حروف انگلیسی، اعداد و آندرلاین باشد»؟
این جمله دقیقاً داره w رو برات توصیف میکنه!
وقتی یه سایت میخواد چک کنه که نام کاربری که تو وارد کردی (مثلاً sareh_bahrani_1990) معتبره و کاراکترهای غیرمجاز مثل فاصله، !، @ یا هشتگ نداره، از یه الگوی رجکس شبیه به این استفاده میکنه: ^w+$
بیا این الگو رو با هم بشکافیم:
^: این علامت یعنی «شروع رشته». به موتور رجکس میگه که بررسی رو از همون ابتدای متن شروع کن.
w+: این همون چیزیه که یاد گرفتیم. یعنی «یک یا چند کاراکتر کلمهای» (حروف، عدد، آندرلاین). اون + خیلی مهمه و معنیش «حداقل یکی یا بیشتر» هست.
$: این علامت یعنی «پایان رشته». میگه الگوی ما باید دقیقاً در انتهای متن تموم بشه.
نتیجه: این الگو (^w+$) تضمین میکنه که کل رشته، از اول تا آخر، فقط و فقط شامل کاراکترهای کلمهای (w) هست. اگه حتی یه فاصله یا یه . وسطش باشه، الگو شکست میخوره و سایت بهت پیغام خطا میده.
استفاده از w+ برای استخراج تمام کلمات از یک متن
این دومین کاربرد بزرگه: «استخراج».
فرض کن یه متن شلوغ داری، مثلاً یه تیکه از یه فایل لاگ یا یه کامنت: “Hey, check out this link: https://vazirseo.com/blog! It’s awesome. #seo”
حالا تو نمیخوای اون علائم نگارشی (:, //, ., !, #) یا فاصلهها رو. تو فقط «کلمهها» و بخشهای معنادار رو میخوای.
اینجا کافیه به موتور رجکس بگی الگوی w+ رو برام پیدا کن. (یادت باشه + یعنی «یک یا چندتا پشت سر هم»).
موتور رجکس اینها رو برای تو پیدا میکنه و برمیگردونه:
Hey
check
out
this
link
https
vazirseo
com
blog
It
s
awesome
seo
دیدی چقدر تمیز شد؟ w+ به محض اینکه به یه کاراکتر «غیر-کلمهای» (W) مثل فاصله، دو نقطه یا هشتگ میرسه، وایمیسته و یه «کلمه» رو برات جدا میکنه. این یه ابزار فوقالعاده قدرتمند برای تمیز کردن و استخراج داده است.
جستجوی کلماتی که شامل عدد هستند (مثلاً user123)
این هم یه سناریوی خیلی رایج دیگه. فرض کن توی URLهای سایتت، توی کامنتها، یا توی دیتابیس محصولاتت، دنبال شناسههایی میگردی که ترکیبی از حرف و عدد هستن. مثلاً:
user123
product_id_A40
v2
خبر خوب اینه که w کار تو رو خیلی راحت کرده!
چون w هم شامل حروف (A-Z, a-z) و هم شامل اعداد (0-9) میشه، الگوی w+ به سادگی تمام این موارد رو برات پیدا میکنه. user123 از نظر w+ یه کلمه یکپارچه و کامل محسوب میشه.
نکته تخصصی (برای حرفهایتر شدن): حالا اگه میخواستی «فقط» کلماتی رو پیدا کنی که «حتماً» توشون هم حرف هست و هم عدد (یعنی user123 رو پیدا کنه ولی user یا 123 رو به تنهایی پیدا نکنه)، اون موقع باید از الگوهای پیشرفتهتری (مثل Lookaheads) استفاده کنی.
اما یه راه سادهتر هم اینه که از میانبر d (به معنی Digit یا عدد) کمک بگیری. مثلاً الگوی w*dw* میتونه کلماتی رو پیدا کنه که «حداقل یک عدد» در جایی وسط خودشون دارن.
کاربردهای عملی W: پاکسازی و جداسازی (Cleaning & Splitting)
W (کاراکتر غیر-کلمه) ابزار فوقالعادهای برای «تمیزکاری» (Sanitization) و «جداسازی» (Splitting) متنهاست. در واقع، ما ازش استفاده میکنیم تا از شر هرچیزی که «کلمه» نیست خلاص بشیم، یا از همونها به عنوان نقطه برش استفاده کنیم.
پاکسازی ورودی: حذف تمام کاراکترهای خاص از یک رشته
این یه سناریوی خیلی رایجه. فرض کن از کاربر یه ورودی میگیری، مثلاً برای «اسلاگ» (Slug) آدرس صفحه یا یه تگ، ولی کاربر یه متن نامرتب وارد میکنه:
ورودی کاربر: “My Cool Post! (#New)”
تو که نمیخوای اون !، (، ) یا # و فاصلهها توی URL سایتت بیان، درسته؟
اینجاست که W مثل یه جاروبرقی عمل میکنه. تو به سادگی میتونی به موتور رجکس بگی: «هر چیزی که W هست رو پیدا کن و با هیچی (یعنی یه رشته خالی “”) جایگزین کن.»
عملیات: جایگزینی (Replace) الگوی W+ با “”.
خروجی تمیز شده: “MyCoolPostNew”
البته معمولاً ما اول همه رو حروف کوچیک میکنیم و بعداً بین کلمات جدا شده خط تیره میذاریم، اما قدم اول کار، یعنی خلاص شدن از شر کاراکترهای خاص، با W انجام میشه. این کار به «پاکسازی یا ضدعفونی کردن ورودی» (Input Sanitization) معروفه و برای امنیت و تمیزی دیتابیس هم حیاتیه.
استفاده از W+ به عنوان جداکننده (Delimiter) در توابع split
این شاید پرکاربردترین و هوشمندانهترین استفاده از W در برنامهنویسی و تحلیل داده باشه.
تقریباً تمام زبانهای برنامهنویسی یه تابع به اسم split() دارن که یه رشته رو میگیره و بر اساس یه «جداکننده» (Delimiter) میشکنه و به یه لیست (آرایه) از کلمات تبدیل میکنه.
معمولاً تو میگی بر اساس فاصله (” “) یا کاما (,) جدا کن. اما اگه متنت شلوغ باشه چی؟ “Hey, how are you? (I’m fine!)”
این متن هم کاما داره، هم علامت سوال، هم پرانتز و هم فاصله.
اینجاست که تو به تابع split() میگی: «به جای یه کاراکتر خاص، بر اساس الگوی رجکس W+ متن من رو بشکن.»
متن: “Hey, how are you? (I’m fine!)”
عملیات: split_by_regex(W+)
خروجی (لیست کلمات): [“Hey”, “how”, “are”, “you”, “I”, “m”, “fine”]
چرا W+(با علامت +)؟ این نکته طلاییه! چون ممکنه چندتا کاراکتر غیر-کلمه پشت هم بیان (مثلاً ? یا (). اون + باعث میشه موتور رجکس همه اونها رو با هم به عنوان یک جداکننده در نظر بگیره و برات کلمات تکراری یا رشتههای خالی (“”) وسط لیستت ایجاد نکنه.
شمارش تعداد علائم نگارشی یا نمادهای خاص در متن
اینم یه کاربرد جالب برای تحلیل داده. فرض کن میخوای بفهمی یه متن چقدر «رسمی» یا «محاورهای» نوشته شده. یکی از فاکتورها میتونه تعداد علائم نگارشی یا نمادها باشه.
تو به راحتی میتونی به موتور رجکس بگی: «تمام W ها رو در این متن برام پیدا کن (Find All) و تعدادشون رو بشمار.»
متن: “Wow! That’s cool.”
پیدا شدهها: ! (تعجب)، (فاصله)، (فاصله)، ‘ (آپاستروف)، . (نقطه)
تعداد: ۵
نکته تخصصی: میدونی جالبترش چیه؟ میتونی از این منطق برعکس هم استفاده کنی. خیلی از سایتها موقع ثبتنام پسورد، بهت میگن: «پسورد باید شامل حداقل یک کاراکتر خاص باشد». اونها در پشت صحنه دقیقاً دارن چک میکنن که آیا رشته پسورد تو، حداقل یک W (کاراکتر غیر-کلمه) داخلش داره یا نه!
نکته تخصصی: تله یونیکد (Unicode) و زبان فارسی
تا اینجا، ما w رو به عنوان معادل [A-Za-z0-9_] تعریف کردیم. این تعریف کلاسیک و «مبنای ASCII» هست. اما دنیای امروز دنیای «یونیکد (Unicode)» هست که شامل تمام زبانهای دنیا، از جمله فارسی، میشه.
اینجاست که یه سوال اساسی پیش میاد و اون میتونه یه «تله» یا «ویژگی» باشه، بستگی به این داره که بدونی داری چیکار میکنی یا نه!
آیا w حروف فارسی (مانند «الف»، «ب») را تطبیق میدهد؟
جواب کوتاه و دقیق اینه: بستگی به موتور Regex تو داره!
در حالت کلاسیک (ASCII-Only): خیر. w فقط و فقط همون [A-Za-z0-9_] هست و حروف فارسی مثل «س»، «ل»، «ا»، «م» رو به عنوان W (غیر-کلمه) میشناسه.
در حالت مدرن (Unicode-Aware): بله! و این همون نکته مهمه.
در موتورهای مدرنی که از یونیکد پشتیبانی میکنن (و معمولاً به صورت پیشفرض فعالش کردن)، تعریف w خیلی گستردهتر میشه. در این حالت، w یعنی: «هر کاراکتری که در استاندارد یونیکد به عنوان “حرف الفبا” (Letter) یا “عدد” (Number) یا “آندرلاین” شناخته میشه.»
چون حروف «الف» تا «ی» هم در استاندارد یونیکd به عنوان «حرف الفبا» تعریف شدن، پس موتورهای یونیکد-آگاه، اونها رو هم بخشی از w حساب میکنن.
تفاوت رفتار w در موتورهای Regex مختلف (Python, JavaScript, PCRE)
این «بستگی دارد» که گفتم، دقیقاً اینجا مشخص میشه. تو باید بدونی ابزاری که داری باهاش کار میکنی، چطور رفتار میکنه:
پایتون (Python 3.x):
پیشفرض: یونیکد (Unicode-Aware) است.
در پایتون ۳، الگوی w بهطور پیشفرض حروف فارسی رو هم تطبیق میده. اگه بنویسی re.findall(r’w+’, ‘سلام world’)، خروجی بهت [‘سلام’, ‘world’] رو میده.
جاوا اسکریپت (JavaScript – ES6+):
پیشفرض: کلاسیک (ASCII-Only) است! (این یه تله خیلی رایجه)
در جاوا اسکریپت، حتی امروز، w به صورت پیشفرض فقط [A-Za-z0-9_] هست و حروف فارسی رو تطبیق نمیده.
راه حل: برای اینکه یونیکد-آگاه بشه، تو باید حتماً از فلگ u در انتهای الگوت استفاده کنی: مثلاً /w+/u.
PCRE (موتور مورد استفاده در PHP و Apache .htaccess):
پیشفرض: معمولاً کلاسیک (ASCII-Only) است.
در PHP (با توابع preg_) تو هم باید از مادیفایر u در انتهای رشته الگو استفاده کنی (مثلاً: ‘/^w+$/u’) تا حروف فارسی و یونیکد رو بشناسه.
چگونه تطبیق را فقط به [A-Za-z0-9_] محدود کنیم؟
حالا یه سناریوی برعکس. فرض کن داری با پایتون ۳ کار میکنی (که پیشفرضش یونیکده)، ولی میخوای یه نام کاربری رو چک کنی و مطمئن بشی که کاربر فقط از حروف انگلیسی، عدد و آندرلاین استفاده کرده و نتونه از حروف فارسی استفاده کنه.
یعنی میخوای جلوی رفتار هوشمند یونیکد رو بگیری و به همون تعریف کلاسیک برگردی.
بهترین، سادهترین و خواناترین راه حل: هیچوقت از میانبر wاستفاده نکن!
به جای اینکه خودت رو درگیر فلگها و تنظیمات موتور رجکس کنی، خیلی واضح و صریح بنویس که دقیقاً دنبال چی هستی:
الگوی اشتباه (در پایتون): ^w+$ (این الگو «سلام» رو هم قبول میکنه)
الگوی صحیح (جهانی): ^[A-Za-z0-9_]+$
وقتی تو به صراحت مینویسی [A-Za-z0-9_]، دیگه هیچ جای شک و شبههای برای هیچ موتور رجکسی باقی نمیمونه. این الگو در پایتون، جاوا اسکریپت، PHP و هر جای دیگهای، دقیقاً یک معنی میده: «فقط حروف انگلیسی، اعداد و آندرلاین».
اینطوری کدت هم خواناتره و هم در برابر تغییرات محیطی (مثل آپدیت شدن نسخه پایتون یا تغییر سرور) مقاومتره.
ارتباط حیاتی: w و W چگونه b (مرز کلمه) را تعریف میکنند؟
b یکی از پراستفادهترین ابزارها در رجکسه. چرا؟ چون به تو اجازه میده دقیقاً خودِ یک کلمه رو پیدا کنی، نه کلمهای که به کلمه دیگهای چسبیده.
مثلاً، اگه تو دنبال کلمه end بگردی، احتمالاً نمیخوای کلمه send یا ending پیدا بشه. تو خودِ end رو میخوای. اینجاست که b وارد میشه (مثلاً با الگوی bendb).
حالا نکته کلیدی اینجاست: هویت و تعریف کامل b تماماً به w و W وابسته است.
تعریف b: موقعیت بین یک w و یک W
این مهمترین چیزیه که باید در مورد b بدونی:
bیک «کاراکتر» نیست.
b نه فاصله است، نه نقطه و نه هیچ چیز دیگهای که دیده بشه. b یک «موقعیت صفر-عرض» (Zero-Width Assertion) هست. یعنی فقط یه «جا» یا یه «موقعیت» رو چک میکنه.
b دقیقاً در موقعیتی قرار میگیره که یک طرفش کاراکتر w (کلمهای) و طرف دیگهش کاراکتر W (غیر-کلمهای) باشه. (یا برعکس: W و بعد w).
بیا یه مثال ساده رو بشکافیم: رشته “Hi!”
موقعیت ۱ (قبل از H): آیا اینجا b هست؟ بله. چون قبلش «هیچی» (که W حساب میشه) و بعدش H (که w هست).
موقعیت ۲ (بین Hو i): آیا اینجا b هست؟ نه. چون H یه w هست و i هم یه w هست. (اینجا مرز نیست، وسط کلمه است).
موقعیت ۳ (بین iو !): آیا اینجا b هست؟ بله! چون i یه w هست و ! یه W هست. (اینجا دقیقاً مرز کلمه است).
پس b یعنی خط مرزی بین قلمرو w و قلمرو W.
چرا درک w برای تسلط بر b ضروری است؟
جواب این سوال حالا باید برات خیلی واضح باشه: چون تعریف bمستقیماً به تعریف wگره خورده.
تو اصلاً نمیتونی «مرز» رو بشناسی، اگه ندونی دو طرف اون مرز چی هستن. b همون خط مرزیه.
اگه تو ندونی w در موتور رجکسی که داری استفاده میکنی دقیقاً شامل چه چیزاییه، اصلاً نمیتونی پیشبینی کنی b کجا قرار میگیره.
یادآوری تله یونیکد (که قبلاً گفتم):
در جاوا اسکریپت (پیشفرض): w حروف فارسی رو نمیشناسه. پس در رشته “سلام!”، از نظر JS هم «م» یه W هست و هم «!» یه W هست. در نتیجه، بین «م» و «!» هیچ مرز کلمهای (b) پیدا نمیکنه!
در پایتون (پیشفرض): w حروف فارسی رو میشناسه. پس در “سلام!”، «م» یه w حساب میشه و «!» یه W. در نتیجه، بین این دو دقیقاً یه b (مرز کلمه) پیدا میکنه.
میبینی؟ تا وقتی روی w و W مسلط نباشی و ندونی تعریف دقیقشون توی ابزار تو چیه، استفاده از b میتونه نتایج کاملاً اشتباهی بهت بده. اول باید تعریف «کلمه» رو بدونی تا بعد بتونی «مرز کلمه» رو پیدا کنی.
جدول مقایسه سریع: w در برابر W
خب، برای اینکه کل این دو مفهوم کلیدی قشنگ برات جا بیفته و همیشه دم دستت باشه، بیا همهچیز رو توی یه جدول مقایسه سریع و ساده خلاصه کنیم:
| ویژگی | w (کوچک) | W (بزرگ) |
|---|---|---|
| نام کامل | کاراکتر کلمه (Word Character) | کاراکتر غیر-کلمه (Non-Word Character) |
| معنی | هر چیزی که بخشی از یک «کلمه» است | هر چیزی که «کلمه» نیست |
| معادل کلاسیک (ASCII) | [A-Za-z0-9_] | [^A-Za-z0-9_] |
| مثالهایی که تطبیق میدهد | A, b, 7, _ | !, ?, $, , . (فاصله، نقطه) |
| مثالهایی که تطبیG نمیدهد | !, ?, $, , . | A, b, 7, _ |
| رابطه با هم | دقیقاً معکوس (Inverse) همدیگر هستند. | |
| کاربرد اصلی | پیدا کردن و استخراج کلمات، شناسهها، نامهای کاربری. | پاکسازی (حذف نمادها)، جداسازی (Split کردن) متن. |
| نقش در تعریف b | یک طرف مرز کلمه را تعریف میکند. | طرف دیگر مرز کلمه را تعریف میکند. |
جمعبندی
خب، تبریک میگم! تو حالا به یکی از اساسیترین بخشهای عبارات باقاعده مسلط شدی. بیا خیلی سریع مرور کنیم چی یاد گرفتیم:
w (کلمه): دوست صمیمی تو برای پیدا کردن هر چیزیه که «کلمه» حساب میشه (حروف، اعداد و آندرلاین). این ابزار اصلی تو برای اعتبارسنجی (مثلاً نام کاربری) و استخراج کلماته.
W (غیر-کلمه): دقیقاً نقطه مقابل قبلیه. این جاروبرقی تو برای پیدا کردن هر چیز «اضافی» مثل فاصلهها، علائم نگارشی و نمادهاست. بهترین کاربردش هم برای پاکسازی ورودیها و جداسازی (Split) متنهاست.
b (مرز کلمه): هم یاد گرفتیم که هویت این مفهوم کاملاً به درک تو از w و W بستگی داره.
از این به بعد تو میتونی با اعتماد به نفس کامل از این میانبرها در کدهات، ابزارهای سئو (مثل اسکریمینگ فراگ) یا گوگل آنالیتیکس استفاده کنی و دقیقاً همون چیزی رو پیدا کنی که دنبالش میگردی.
سوالات متداول (FAQ)
۱. آیا w حروف فارسی مثل «سلام» را هم پیدا میکند؟
این سوال عالیه و جوابش «بستگی داره»! در موتورهای رجکس مدرن که از یونیکد (Unicode) پشتیبانی میکنن (مثل پایتون ۳)، بله، w حروف فارسی رو هم «کلمه» حساب میکنه. اما در موتورهای کلاسیک یا جاهایی که حالت یونیکد فعال نباشه (مثل جاوا اسکریپت بدون فلگ u)، نه، حروف فارسی W (غیر-کلمه) محسوب میشن.
۲. چرا آندرلاین (_) جزو w (کاراکتر کلمه) حساب میشود؟
دلیلش کاملاً تاریخیه و به زبانهای برنامهنویسی برمیگرده. در زبانهایی مثل C، برنامهنویسها از آندرلاین برای ساختن اسم متغیرهای چند کلمهای استفاده میکردن (مثلاً user_name). چون رجکس اول برای کار با کد ساخته شد، _ رو به عنوان بخشی از «کلمه» پذیرفت.
۳. تفاوت w با w+ چیست؟
w (خالی) فقط یک کاراکتر کلمه رو پیدا میکنه. اما اون علامت + (Quantifier) معنیش اینه که «یک یا چندتا» از کاراکتر قبلی (یعنی w) که پشت سر هم اومدن. پس w+ کل کلمه «sara123» رو به صورت یکجا پیدا میکنه، ولی w فقط «s» رو پیدا میکنه.
۴. نقطه مقابل b (مرز کلمه) چیست؟
نقطه مقابلش B (با B بزرگ) هست. B یعنی «موقعیتی که مرز کلمه نیست». یعنی جایی که دو طرفش هر دو w هستن (وسط یه کلمه) یا هر دو W هستن (وسط یه رشته از علائم).