Как обернуть слова или последовательности слов, которые еще не были обернуты?

StackOverflow https://stackoverflow.com/questions/3923901

  •  29-09-2019
  •  | 
  •  

Вопрос

Я пытаюсь завершить последовательность слов и слов из данного списка с preg_replace. Это почти работает, но есть некоторые варианты использования, и я не могу понять, как.

Например, я делаю это:

    // sort by descending length
    usort($this->_keywords, function($a,$b){return(strlen($a)<strlen($b));});

    // wrapper is -%string%-
    foreach ($this->_keywords as $keyword) {
        $value = preg_replace('/((?!-)' . $keyword . '(?!-))/i', str_replace('%string%', '\1', $this->_wrapper), $value);
    }

Из этого списка ключевых слов:

  • Лорем
  • ipsum
  • сидеть амит
  • нулевой
  • Сед
  • Sed Enim

Я хотел бы привести к:

-Лум- -Пипсум- Долор -Сит амет-, Consectetur Adipiscing Elit. Phasellus rhoncus venenatis orci sed porta. SED NON DOLOR EROS. Приостановка Масса -Сит амет- Nulla Egestas farsilisis. Cras Fringilla, Leo Ac Ullamcorper Semper, Urna Eros Pretium Lectus, Nec Rhoncus Ligula Risus Eu Velit. Nulla Eu Dapibus Magna. SED ETHICULA TRISTIQUE LACINIA. Maecenas tincidunt Metus в Urna exclive nec Congue Libero Iaculis. Nulla farsilisi. Phasellus -сед-Sem ut Risus mattis accumsan eu -Пет Enim-. Анкет Pallentesque Hainatant Morbi Tristique Senectus et Netus et Malesuada Fames ac turpis egestas. SUSPERNDISSE ID EST VELIT, EU Cursus Quam. Vivamus lacinia euuismod pretium.

Любые идеи?

Это было полезно?

Решение 2

Я наконец решил свои проблемы, используя \b Метахарактеры, которые соответствуют границе слова.

public function filter($value)
{
    usort($this->_keywords, function($a,$b){return(strlen($a)<strlen($b));});

    foreach ($this->_keywords as $keyword) {
        $value = preg_replace(
            '/((?<!-)('.$keyword.'\b)(?!\-))/i',
            str_replace('%string%', '\2', $this->_wrapper) . '\3',
            $value
        );
    }

    return $value;
}

Другие советы

Проще всего использовать preg_replace_callback(), и сопоставьте слова, которые уже были завернуты, и каждое ключевое слово. Когда матч - это слово, которое было обернуто, просто верните его немодифицированным. Нет необходимости в проблемных взглядах.

function compare_length($a, $b) {
    return strlen($a) < strlen($b);
}

function build_regex($keywords) {
    usort($keywords, 'compare_length');
    $pieces []= '/(?<wrapped>-[\w\s]*-)|(?<keyword>';
    for ($i = 0; $i < count($pieces); $i++) {
        if ($i > 0) $pieces []= '|';
        $pieces []= preg_quote($keywords[$i], '/');
    }
    $pieces []= ')/';
    return implode("", $pieces);
}

function wrap_callback($match) {
    if (!empty($match['wrapped'])) {
        return $match['wrapped'];
    }
    return "-{$match['wrapped']}-";
}

function wrap($text, $keywords) {
    $regex = build_regex($keywords);
    return preg_replace_callback($regex, 'wrap_callback');
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top