Preg Replace - заменить второе вхождение матча - PullRequest
0 голосов
/ 16 апреля 2011

Я относительно новичок в php, и надеюсь, что кто-нибудь может помочь мне с заменой регулярных выражений, или, возможно, замена замены, я не совсем уверен.

Я хочу автоматически выделить жирным шрифтом (второе вхождение совпадения), а затем сделать 4-е появление курсива матча, а затем 7-е появление совпадения.

Это в основном для целей SEO в контенте.

Я сделал несколько замен на: и думал, что это должно сработать?

preg_replace( pattern, replacement, subject [, limit ])

Я уже знаю слово, которое хочу использовать в

'pattern' is also a word that is already defined like [word].
`replacement` 'This is a variable I am getting from a mysql db.
'subject' - The subject is text from a db.

Допустим, у меня есть это содержание: это объясняет более или менее то, что я хочу сделать.

Это пример текста, который я хочу заменить. В этом тексте я хочу сделать второе вхождение слова пример <жирным шрифтом. Затем я хочу пропустить следующий раз, когда пример встречается в тексте, и сделать четвертый раз, когда слово <strong>пример выделено курсивом. Затем я хочу пропустить 5-й раз, когда слово «пример» появляется в тексте, а также 6-й раз и, наконец, хочу, чтобы 7-й раз пример появился в тексте, подчеркните его. В этом примере я использовал гиперссылку в качестве примера подчеркивания, так как я не вижу функции подчеркивания в текстовом редакторе. Слово «пример» может появляться в тексте несколько раз, но мое единственное требование - подчеркнуть один раз, выделить один раз жирным шрифтом и один раз выделить курсивом. Позже я могу также взять несколько цитат из слова «пример», но это еще не приоритет.

Также важно, чтобы код не проходил через ошибку, если не было хотя бы 7 вхождений слова.

Как бы я это сделал, любые идеи будут оценены.

Ответы [ 3 ]

3 голосов
/ 16 апреля 2011

Вы можете использовать preg_split, чтобы разделить текст в матчах, применить изменения, а затем собрать все вместе:

$parts = preg_split('/(example)/', $str, 7, PREG_SPLIT_DELIM_CAPTURE);
if (isset($parts[3])) $parts[3] = '<b>'.$parts[3].'</b>';
if (isset($parts[7])) $parts[7] = '<i>'.$parts[7].'</i>';
if (isset($parts[13])) $parts[13] = '<u>'.$parts[13].'</u>';
$str = implode('', $parts);

Формула индекса для i-это совпадение index = i · 2 - 1.

3 голосов
/ 16 апреля 2011

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

// just counting
if (7 >= preg_match_all($pattern, $subject, $matches)) {

   $cb_num = 0;
   $subject = preg_replace_callback($pattern, "cb_ibu", $subject);
}

function cb_ibu($match) {
    global $cb_num;

    $match = $match[0];

    switch (++$cb_num) {
        case 2: return "<b>$match</b>";
        case 4: return "<i>$match</i>";
        case 7: return "<u>$match</u>";
        default: return $match;
    }
}

Хитрость заключается в том, чтобы иметь обратный вызов, который выполняет учет.И там довольно легко добавить любые правила.

0 голосов
/ 16 апреля 2011

Это интересный вопрос.Моя реализация будет:

function replace_exact($word, $tag, $string, $limit) {
    $tag1 = '<'.$tag.'>';
    $tag2 = '</'.$tag.'>';
    $string = str_replace($word, $tag1.$word.$tag2, $string, 1);
    if ($limit==1) return $string;
    return str_replace($tag1.$word.$tag2,$word,$string,$limit-1);
}

Используйте это так:

echo replace_exact('Example', 'b', $source_text, 2);
echo replace_exact('Example', 'i', $source_text, 4);

Я не знаю, как быстро это будет работать, но это будет быстрее, чем preg_replace.

...