تابع strspn() در PHP
تابع strspn() یکی از توابع رشتهای ساده ولی کاربردی در PHP است که برای محاسبه طول بخش ابتدایی یک رشته (prefix) استفاده میشود که تنها از کاراکترهای مشخصشده در یک ماسک تشکیل شده باشد. این تابع در بسیاری از موارد ساده و پرکاربرد مانند اعتبارسنجی، پارسینگ سریع یا یافتن طول توالی مجاز در ابتدای یک رشته مفید است.
تعریف و امضا (signature)
| امضا | توضیح |
|---|---|
int strspn(string $haystack, string $mask [, int $start = 0 [, int $length ]]) | طول بیشترین پیشوندی از haystack که تنها شامل کاراکترهای موجود در mask است. شروع از موقعیت start و بررسی تا طول اختیاری length. |
رفتار کلی
- strspn تعداد بایتهایی در ابتدای رشته را برمیگرداند که فقط شامل کاراکترهای داخل ماسک هستند.
- اگر اولین کاراکتر هم در ماسک نباشد، مقدار 0 بازمیگردد.
- تابع بر اساس بایت کار میکند؛ بنابراین در رشتههای چندبایتی (UTF-8) باید احتیاط کرد.
مثالهای پایه
<?php
echo strspn("123abc", "0123456789"); // خروجی: 3
echo "n";
echo strspn("abc123", "abc"); // خروجی: 3
echo "n";
echo strspn("xyz123", "abc"); // خروجی: 0
?>توضیح: در مثال اول، از ابتدای رشته “123abc” سه کاراکتر اول (1،2،3) همگی در ماسک ارقام قرار دارند، بنابراین مقدار 3 برگردانده میشود. در سومین مثال، اولین کاراکتر ‘x’ در ماسک “abc” نیست و تابع 0 برمیگرداند.
استفاده از پارامترهای start و length
<?php
$str = "abc123abc";
echo strspn($str, "abc", 0); // از ابتدای رشته، خروجی: 3
echo "n";
echo strspn($str, "abc", 3); // از ایندکس 3 شروع کند: خروجی: 3 (برای "123" اما هیچکدام در ماسک نیستند پس 0)
echo "n";
echo strspn($str, "123abc", 3); // از موقعیت 3 (شروع از "123abc"), خروجی: 6
?>توضیح: پارامتر سوم (start) مشخص میکند از کدام ایندکس بررسی آغاز شود. پارامتر چهارم (length) اگر تعیین شود بررسی در محدودهای محدود انجام میشود.
مثال کاربردی: اعتبارسنجی رشته
<?php
$input = "user_name123";
$allowed = "abcdefghijklmnopqrstuvwxyz0123456789_";
if (strspn($input, $allowed) === strlen($input)) {
echo "تمام کاراکترها مجاز هستند.";
} else {
echo "کاراکتر نامجاز در رشته وجود دارد.";
}
?>توضیح: با مقایسه مقدار بازگشتی strspn با طول کل رشته میتوان بررسی کرد که آیا همه کاراکترها از مجموعه مجاز هستند یا خیر. این روش برای اعتبارسنجی کاراکترها سریع و مؤثر است.
مقایسه با توابع دیگر
- strcspn(): برعکس strspn عمل میکند و طول پیشوندی را برمیگرداند که شامل هیچیک از کاراکترهای ماسک نباشد (مناسب برای یافتن اولین کاراکتر متعلق به ماسک).
- preg_match(): الگوهای پیچیدهتر و پشتیبانی از یونیکد را فراهم میکند اما معمولاً سنگینتر از strspn است.
- ctype_* (): مجموعهای از توابع برای بررسی نوع کاراکتر (مانند ctype_digit) که در برخی موارد خواناتر و سریعتر هستند.
نکته مهم: مولتیبایت (UTF-8) و محدودیتها
تابع strspn بر اساس بایت کار میکند، نه بر اساس کاراکترهای یونیکد. بنابراین در رشتههای UTF-8 که کاراکترها چند بایتی هستند، نتایج ممکن است غیرمنتظره باشند. برای پردازش متنهای چندبایتی از توابع mb_* یا از عبارات منظم با مود /u استفاده کنید.
<?php
$s = "سلام"; // هر کاراکتر چند بایتی است
echo strlen($s); // تعداد بایتها، نه تعداد کاراکترها
echo "n";
echo strspn($s, "لا"); // ممکن است بهدلیل بایتی بودن نادرست رفتار کند
?>توضیح: در این موارد بهتر است از preg_match('/^[p{Arabic}]+/u', $s, $m) یا تبدیل به آرایهای از کاراکترها با mb_substr و بررسی کاراکتر به کاراکتر استفاده کنید.
بهینهسازی و نکات عملکردی
- برای موارد ساده و پرسرعت که بررسی مجموعهای از کاراکترها در ابتدای رشته است، strspn معمولاً از regex سریعتر است.
- اگر نیاز به محاسبه تعداد کاراکترهای مجاز در وسط رشته دارید، ممکن است ترکیب strcspn و strspn مفید باشد.
- برای بررسی نوع کاراکترهای مشخص (اعداد، حروف) توابع ctype_* میتوانند خواناتر و گاهی سریعتر باشند.
مثال پیشرفته: پیدا کردن اولین توالی مجاز پس از مکان مشخص
<?php
$text = "!!!123abc--rest";
$pos = strcspn($text, "0123456789"); // موقعیت اولین عدد
$len = strspn(substr($text, $pos), "0123456789"); // طول توالی اعداد از آن نقطه
echo "شروع: $pos, طول: $lenn"; // خروجی: شروع: 3, طول: 3
?>توضیح: در این مثال ابتدا با strcspn به محل اولین کاراکتر از ماسک رسیدیم، سپس با strspn طول توالی مجاز را از آن نقطه محاسبه کردیم. ترکیب این دو تابع برای پارس کردن رشتهها بسیار مفید است.
نکات امنیتی و کاربردها
- برای فیلتر کردن کاراکترهای ناخواسته در دادههای ورودی (مثلاً نام کاربری)، strspn یک ابزار ساده و سریع است.
- برای بررسی الگوهای پیچیدهتر یا پشتیبانی از یونیکد، از روشهای دیگر (regex با /u یا mb_ توابع) استفاده کنید.
- در تعریف ماسک دقت کنید: ماسک یک لیست از کاراکترهاست و محدودهها (مثل 0-9) بهطور خودکار تفسیر نمیشوند؛ برای اعداد از
0123456789یا ctype_digit کمک بگیرید.
خلاصه
strspn() تابعی سبک و سریع برای تعیین طول پیشوندی است که فقط از یک مجموعه مشخص از کاراکترها تشکیل شده. مناسب برای اعتبارسنجی ساده، پارس کردن روزمره و بهینهسازیهایی که نیازی به regex ندارند. اما هنگام کار با متنهای یونیکد یا نیاز به دامنههای پیچیده، از توابع چندبایته یا عبارتهای منظم استفاده کنید.
آیا این مطلب برای شما مفید بود ؟



