質問

特定のリストから単語と単語のシーケンスを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
  • AMETを座ります
  • ヌル
  • sed
  • sed enim

結果をもたらしたい:

- lorem- -IPSUM- ドロール -sit amet-、補給エリットの脂肪が切断されます。 Phasellus Rhoncus venenatis orci sed porta。 sed non dolor eros。マッサをサスペンディスします -sit amet- nulla egestas facilisis。 Cras Fringilla、Leo Ac UllamCorper Semper、Urna Eros Pretium Lectus、Nec Rhoncus ligula risus eu velit。 nulla eu dapibus magna。 sed hearicula tristique lacinia。 urnaのMaecenas Tincidunt Metusは、Nec Congue Libero Iaculisを結果として生成します。 nulla facilisi。フェセラス -sed-sem ut risus mattis accumsan eu -sed enim-. 。 Pellentessque Habitant Morbi Tristique senectus et netus et malesuada fames ac turpis egestas。 suspendisse id est velit、eu cursus quam。 Vivamus Lacinia Euismod 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