تابع str_word_count() در PHP
تابع str_word_count() یکی از توابع ساده و کاربردی در PHP برای استخراج یا شمارش کلمات داخل یک رشته است. این تابع در حالت پایه برای متنهای لاتین و کاراکترهای ASCII طراحی شده و سه حالت بازگشتی مختلف دارد. در ادامه به پارامترها، مثالهای واقعی، محدودیتها و راهکارهای جایگزین برای متنهای غیرلاتین (مثل فارسی یا یونیکد) میپردازیم.
امضای تابع و پارامترها
| پارامتر | توضیح |
|---|---|
| string | رشته ورودی |
| format (اختیاری) | 0 (پیشفرض): بازگشت تعداد کلمات (int) 1: بازگشت آرایهای از کلمات (array) 2: بازگشت آرایه انجمنی با کلید موقعیت (offset) و مقدار کلمه (array) |
| charlist (اختیاری) | لیست اضافی از کاراکترهایی که باید جزئی از کلمه محسوب شوند (مثلاً ‘ یا -) |
مثالهای پایهای
<?php
$text = "Hello, world! This is PHP.";
// حالت 0: تعداد کلمات
$count = str_word_count($text);
var_dump($count); // int(5)
// حالت 1: آرایه کلمات
$words = str_word_count($text, 1);
var_dump($words); // array(5) { [0]=> string(5) "Hello" ... }
// حالت 2: آرایه با موقعیت
$pos = str_word_count($text, 2);
var_dump($pos); // array(5) { [0]=> string(5) "Hello" [7]=> string(5) "world" ... }
?>در این مثال تابع تعداد کلمات را میشمارد، لیستی از کلمات را برمیگرداند و همچنین میتوان موقعیت بایت (offset) هر کلمه را دریافت کرد. توجه داشته باشید که offset برحسب بایت است نه حتماً کاراکتر در متنهای چندبایتی.
استفاده از charlist برای شامل کردن کاراکترهای خاص
<?php
$text = "Don't stop.";
// شامل کردن ' به عنوان بخشی از کلمه
$words = str_word_count($text, 1, "'");
var_dump($words); // array(2) { [0]=> string(5) "Don't" [1]=> string(4) "stop" }
?>در این نمونه با استفاده از پارامتر سوم (charlist) علامت آپاستروف را جزئی از کلمه در نظر گرفتهایم تا “Don’t” به صورت یک کلمه استخراج شود.
محدودیتهای مهم و رفتار در مقابل متنهای Unicode (مثل فارسی)
- تابع str_word_count() بهصورت پیشفرض فقط کاراکترهای لاتین (A–Z, a–z) را بهعنوان کلمه میشناسد.
- برای متنهای غیرلاتین مانند فارسی، عربی یا چینی این تابع معمولاً تعداد صفر یا نتایج نادرست بازمیگرداند، زیرا از UTF-8 پشتیبانی مستقیم نمیکند.
- پارامتر charlist نیز برای افزودن حروف یونیکد بهدرستی قابل استفاده نیست چرا که این پارامتر با توجه به پردازش بایتی کار میکند.
بنابراین برای پردازش متنهای فارسی/یونیکد باید از روشهای مبتنی بر الگوهای یونیکد (PCRE with /u) یا توابع چندبایتی استفاده کنیم.
جایگزین مناسب برای متنهای فارسی و یونیکد
<?php
$text = "سلام دنیا! PHP و پردازش متن.";
// استفاده از preg_match_all با گروه یونیکد p{L} برای حروف
preg_match_all('/[p{L}p{M}p{N}]+/u', $text, $matches);
$words = $matches[0];
$count = count($words);
var_dump($count, $words);
?>کد بالا با الگوی یونیکد p{L} (حروف)، p{M} (علامتهای ترکیبی مثل اعراب)، p{N} (اعداد) کلمات را استخراج میکند. گزینه u برای حالت Unicode ضروری است. این روش برای فارسی، عربی و زبانهای دیگر با نویسههای غیرلاتین دقیقتر عمل میکند.
استخراج موقعیت (offset) کلمات در متن یونیکد
<?php
$text = "سلام دنیا، متن تست.";
// استخراج کلمات با موقعیت بایت
preg_match_all('/[p{L}p{M}p{N}]+/u', $text, $matches, PREG_OFFSET_CAPTURE);
$results = [];
foreach ($matches[0] as $m) {
$word = $m[0];
$byteOffset = $m[1];
// تبدیل آفست بایت به آفست کاراکتری
$charOffset = mb_strlen(mb_substr($text, 0, $byteOffset, 'UTF-8'), 'UTF-8');
$results[$charOffset] = $word;
}
var_dump($results);
?>الگوی بالا با PREG_OFFSET_CAPTURE موقعیت بایت را فراهم میکند. برای تبدیل به موقعیت برحسب کاراکتر از توابع mb_ استفاده شده تا آفست دقیق در متنهای چندبایتی بهدست آید.
نکات عملکردی و بهترین روشها
- برای متنهای لاتین ساده، استفاده از str_word_count سریع و کافی است.
- برای متنهای یونیکد و فارسی از preg_match_all با الگوهای p{L}p{M} و پرچم /u استفاده کنید.
- اگر میخواهید کلماتی مانند don’t یا word-with-hyphen را بهصورت یک کلمه شناسایی کنید، از charlist در str_word_count برای متن لاتین یا در الگوهای preg از شمول ‘ و – استفاده کنید.
- برای محتوای حجیم، عملکرد preg_match_all میتواند هزینهبر باشد؛ تست و پروفایلینگ روی نمونههای واقعی توصیه میشود.
خلاصه و توصیههای عملی
تابع str_word_count() ابزار سریع و سادهای برای شمارش و استخراج کلمات در متنهای لاتین است و سه mode مفید برای نیازهای مختلف ارائه میدهد. اما برای متنهای غیرلاتین مانند فارسی یا مواقعی که نیاز به پشتیبانی از یونیکد دارید، بهتر است از الگوهای PCRE با پرچم Unicode یا توابع چندبایتی استفاده کنید تا نتایج دقیق و قابل اطمینانی بهدست آورید.
آیا این مطلب برای شما مفید بود ؟



