我正在尝试使用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
  • SED Enim

我想导致:

-lorem- -IPPUM- Dolor -Sit amet-,Consettur adipiscing Elit。 Phasellus rhoncus venenatis orci sed Porta。 sed non dolor eros。暂停Massa -Sit amet- Nulla Egestas的功能。 Cras Fringilla,Leo Ac ullamcorper Semper,Urna Eros lectum lectus,Nec rhoncus ligula ligula risus eu velit。 Nulla Eu Dapibus Magna。 SED Vehicula Tristique Lacinia。 Maecenas tincidunt Metus在Urna Reactation Nec会助理Libero Iaculis。 Nulla Facilisi。 phasellus -Sem Risus Mattis累积欧盟 - eNim-. 。 Pellentesque居民Morbi Tristique Senectus et Netus et Malesuada fames ac turpis egestas。悬挂式,欧盟的cursus Quam。 Vivamus lacinia euismod pretium。

有任何想法吗?

有帮助吗?

解决方案 2

我终于通过使用 \b 与单词边界相对应的metacharacters。

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