۳۱ ژانویه ۲۰۲۳

یونیکد: پرچم "u" و کلاس {...}p\

جاوااسکریپت از رمزگذاری یونیکد برای رشته ها استفاده می کند. اکثر کاراکترها با 2 بایت کدگذاری می شوند، اما این امکان را برای نمایش حداکثر 65536 کاراکتر فراهم می کند.

این محدوده به اندازه کافی بزرگ نیست تا همه کاراکترهای ممکن را رمزگذاری کند، به همین دلیل است که برخی از کاراکترهای کمیاب با 4 بایت کدگذاری می شوند، به عنوان مثال مانند 𝒳 (X ریاضی) یا 😄 (لبخند)، برخی از هیروگلیف ها و غیره.

در اینجا مقادیر یونیکد برخی از کاراکترها آمده است:

کاراکتر یونیکد تعداد بایت یونیکد
a 0x0061 2
0x2248 2
𝒳 0x1d4b3 4
𝒴 0x1d4b4 4
😄 0x1f604 4

بنابراین کاراکتر هایی مانند a و 2 بایت را اشغال می کنند، در حالی که کدهای 𝒳، 𝒴 و 😄 طولانی تر هستند و 4 بایت دارند.

مدت ها پیش، زمانی که زبان جاوااسکریپت ایجاد شد، رمزگذاری یونیکد ساده تر بود: هیچ کاراکتر 4 بایتی وجود نداشت. بنابراین برخی از ویژگی های زبان را به اشتباه مدیریت می کردند.

به عنوان مثال، length فکر می کند که در اینجا دو کاراکتر وجود دارد:

alert('😄'.length); // 2
alert('𝒳'.length); // 2

…اما ما می توانیم ببینیم که فقط یک کاراکتر وجود دارد، درست است؟ نکته این است که length آن 4 بایت را به عنوان دو کاراکتر 2 بایتی در نظر می گیرد. این نادرست است، زیرا آنها باید فقط با هم در نظر گرفته شوند (به اصطلاح “surrogate pair”، می توانید در مورد آنها در مقاله رشته‌ها بخوانید).

به‌ طور پیش‌ فرض، عبارات باقاعده نیز “کاراکتر های طولانی” 4 بایتی را به عنوان یک جفت 2 بایتی در نظر می‌ گیرند. همانطور که در مورد رشته ها اتفاق می افتد، ممکن است به نتایج عجیب و غریب منجر شود. این را کمی بعد، در مقاله Sets and ranges [...] خواهیم دید.

برخلاف رشته‌ها، عبارات باقاعده دارای پرچم u هستند که چنین مشکلاتی را برطرف می‌ کند. با چنین پرچمی، یک regexp کاراکترهای 4 بایتی را به درستی مدیریت می کند. همچنین جستجوی ویژگی یونیکد در دسترس قرار می گیرد. در ادامه به آن خواهیم پرداخت.

ویژگی های یونیکد {…}p\

هر کاراکتر در یونیکد دارای ویژگی های زیادی است. آنها توصیف می کنند که کاراکتر به چه “رده ای” تعلق دارد و حاوی اطلاعات متفرقه در مورد آن است.

به عنوان مثال، اگر یک کاراکتر دارای ویژگی Letter باشد، به این معنی است که کاراکتر متعلق به الفبا (از هر زبان) است. ویژگی Number به این معنی است که آن کاراکتر یک رقم است: شاید عربی یا چینی و غیره.

می‌ توانیم کاراکترهایی را با یک ویژگی جستجو کنیم که به صورت {…}pattern:\p نوشته شده است. برای استفاده از {…}pattern:\p، یک عبارت باقاعده باید دارای پرچم u باشد.

برای مثال، {Letter}p\ یک حرف در هر زبانی را نشان می‌دهد. همچنین می‌ توانیم از p{L}\ استفاده کنیم، زیرا L نام مستعار Letter است. تقریباً برای هر ویژگی نام مستعار کوتاه تری وجود دارد.

در مثال زیر سه نوع حرف وجود دارد: انگلیسی، گرجی و کره ای.

let str = "A ბ ㄱ";

alert( str.match(/\p{L}/gu) ); // A,ბ,ㄱ
alert( str.match(/\p{L}/g) ); // null (کار نمی کند "u" بدون پرچم \p ،بدون انطباق)

در اینجا دسته بندی کاراکتر های اصلی و زیر شاخه های آنها آمده است:

  • حرف L:
    • حروف کوچک Ll
    • اصلاح کننده Lm,
    • عنوان Lt,
    • حروف بزرگ Lu,
    • سایر Lo.
  • عدد N:
    • رقم اعشاری Nd,
    • شماره نامه Nl,
    • سایر No.
  • نقطه گذاری P:
    • اتصال دهنده Pc,
    • خط تیره Pd,
    • نقل قول اولیه Pi,
    • نقل قول نهایی Pf,
    • باز Ps,
    • بسته Pe,
    • سایر Po.
  • علامت M (لهجه ها و غیره):
    • ترکیب فاصله Mc,
    • محصور کردن Me,
    • بدون فاصله Mn.
  • نماد S:
    • واحد پول Sc,
    • اصلاح کننده Sk,
    • ریاضی Sm,
    • سایر So.
  • جداکننده Z:
    • خط Zl,
    • پاراگراف Zp,
    • فاصله Zs.
  • سایر