سؤال

أحاول التوصل إلى الوظيفة التالية التي تقطع السلسلة إلى كلمات كاملة (إن أمكن ، وإلا يجب أن تقطع إلى chars):

function Text_Truncate($string, $limit, $more = '...')
{
    $string = trim(html_entity_decode($string, ENT_QUOTES, 'UTF-8'));

    if (strlen(utf8_decode($string)) > $limit)
    {
        $string = preg_replace('~^(.{1,' . intval($limit) . '})(?:\s.*|$)~su', '$1', $string);

        if (strlen(utf8_decode($string)) > $limit)
        {
            $string = preg_replace('~^(.{' . intval($limit) . '}).*~su', '$1', $string);
        }

        $string .= $more;
    }

    return trim(htmlentities($string, ENT_QUOTES, 'UTF-8', true));
}

فيما يلي بعض الاختبارات:

// Iñtërnâtiônàlizætiøn and then the quick brown fox... (49 + 3 chars)
echo dyd_Text_Truncate('Iñtërnâtiônàlizætiøn and then the quick brown fox jumped overly the lazy dog and one day the lazy dog humped the poor fox down until she died.', 50, '...');

// Iñtërnâtiônàlizætiøn_and_then_the_quick_brown_fox_...  (50 + 3 chars)
echo dyd_Text_Truncate('Iñtërnâtiônàlizætiøn_and_then_the_quick_brown_fox_jumped_overly_the_lazy_dog and one day the lazy dog humped the poor fox down until she died.', 50, '...');

كلاهما يعملان كما هو ، ولكن إذا أسقطت الثانية preg_replace() أحصل على ما يلي:

iñtërnâtiônàlizætiøn_and_then_the_quick_brown_fox_jumped_overly_the_lazy_dog وفي يوم من الأيام ، قام الكلب الكسول بحماس الثعلب الفقير إلى أسفل حتى ماتت ....

لا يمكنني استخدام substr() لأنه يعمل فقط على مستوى البايت وليس لدي إمكانية الوصول إليه mb_substr() ATM ، لقد بذلت عدة محاولات للانضمام إلى Regex الثاني مع أول واحد ولكن دون نجاح.

الرجاء مساعدة الرسائل القصيرة ، لقد كنت أعاني من هذا لمدة ساعة تقريبًا.


تحرير: أنا آسف ، لقد كنت مستيقظًا لمدة 40 ساعة وفقدت هذا دون خجل:

$string = preg_replace('~^(.{1,' . intval($limit) . '})(?:\s.*|$)?~su', '$1', $string);

ومع ذلك ، إذا كان لدى شخص ما regex أكثر تحسنا (أو واحد يتجاهل المساحة الخلفية) يرجى المشاركة:

"Iñtërnâtiônàlizætiøn and then "
"Iñtërnâtiônàlizætiøn_and_then_"

تحرير 2: ما زلت لا أستطيع التخلص من المسافة البيضاء الزائدة ، هل يمكن لأحد أن يساعدني؟

تحرير 3: حسنًا ، لم ينجح أي من تعديلاتاتي حقًا ، لقد كنت ينخدع بواسطة regexbuddy - ربما يجب أن أترك هذا ليوم آخر وأحصل على بعض النوم الآن. قبالة لهذا اليوم.

هل كانت مفيدة؟

المحلول

ربما يمكنني أن أعطيك صباحًا سعيدًا بعد ليلة طويلة من كوابيس Regexp:

'~^(.{1,' . intval($limit) . '}(?<=\S)(?=\s)|.{'.intval($limit).'}).*~su'

غليه:

^      # Start of String
(       # begin capture group 1
 .{1,x} # match 1 - x characters
 (?<=\S)# lookbehind, match must end with non-whitespace 
 (?=\s) # lookahead, if the next char is whitespace, match
 |      # otherwise test this:
 .{x}   # got to x chars anyway.
)       # end cap group
.*     # match the rest of the string (since you were using replace)

يمكنك دائما إضافة |$ حتى نهاية (?=\s) ولكن نظرًا لأن الرمز الخاص بك كان يتحقق بالفعل من أن طول السلسلة كان أطول من $limit, ، لم أشعر أن هذه القضية ستكون ضارة.

نصائح أخرى

هل فكرت في استخدام WordWrap؟ ((http://us3.php.net/wordwrap)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top