Задать вопрос

На английском работает, на русском нет. Проблема с preg_match_all

Есть вот такая функция:

function summarize($haystack,$needle,$wordLimit = 5) {


    // first get summary of text around key word (needle)
    $preg_safe = str_replace(" ", "\s", preg_quote($needle));
    
    $pattern = "/(\w*\S\s+){0,$wordLimit}\S*\b($preg_safe)\b\S*(\s\S+){0,$wordLimit}/iux";
    if (preg_match_all($pattern, $haystack, $matches)) {
        $summary = str_replace(strtolower($needle), "<strong>$needle</strong>", $matches[0][0]) . '…';
    } else {
        $summary = false;
    }

    return $summary;
}


Она выбирает часть длинного текста из $haystack вокруг найденного $needle. Это нужно чтобы показать пользователю часть найденного текста вокруг этого поискового запроса.

Если текст на входе английский, то работает. Если русский, то не работает. Использовал конвертацию в cp1251, но не помогло. В регулярке стоит флаг «u», который должен помочь, но не помогает.

Тестировать можно на таком вызове функции:
echo summarize("тут очень много текста на входе","на");


А вот так работает:
echo summarize("Lorem ipsum dollar","ipsum");
  • Вопрос задан
  • 3601 просмотр
Подписаться 10 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 4
@Monaxxx
Добавил функцию

function fixEncoding($s, $encoding = 'UTF-8') {   
    $s = @iconv('UTF-16', $encoding . '//IGNORE', iconv($encoding, 'UTF-16//IGNORE', $s)); 
    return str_replace("\xEF\xBB\xBF", '', $s);
}

в твой код

function summarize($haystack, $needle, $wordLimit = 5) {

    $haystack = fixEncoding($haystack);
    $needle = fixEncoding($needle);
    // first get summary of text around key word (needle)
    $preg_safe = str_replace(" ", "\s", preg_quote($needle));

    $pattern = "/(\w*\S\s+){0,$wordLimit}\S*\b($preg_safe)\b\S*(\s\S+){0,$wordLimit}/iux";
    if (preg_match_all($pattern, $haystack, $matches)) {
        $summary = str_replace(strtolower($needle), "<strong>$needle</strong>", $matches[0][0]) . '…';
    } else {
        $summary = false;
    }

    return $summary;
}


Работает
Ответ написан
Комментировать
xrays72
@xrays72
Ответ написан
Комментировать
CGS
@CGS
Попробуйте:
setlocale(LC_ALL, 'ru_RU.CP1251');
Ответ написан
Комментировать
nazarpc
@nazarpc
Open Source enthusiast
Сама строка на входе в utf-8? Может, вы файл сохранили в Win-1251?
У меня оба ваших примера работают!
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы