Nano Hash - криптовалюты, майнинг, программирование

preg_replace внутри цикла заменяет последнее совпадение вместо каждого

Извините за заголовок, честно говоря, не знаю, как его правильно объяснить.

Я делаю небольшую функцию шорткода, которая должна заменить шорткоды выводом html.

preg_match_all находит все, что мне нужно, но preg_replace заменяет одно и то же совпадение снова и снова. Вот демо https://eval.in/139727

Я уверен, что сделал беспорядок в этих циклах foreach, но просто не могу понять это.

$text = 'Some text and some [link link="linkhref1" text="Text1"],[link link="linkhref2" text="Text2"]';


function shortcodes($text) {
    $shortcodes = array(
        'link' => array(
            "check" => "[link",
            "type" => "link",
            "match" => "#\[link(.*?)link\=\"(.*?)\"(.*?)text\=\"(.*?)\"#Ui",
            "replace" => "/\[link(.*?)\]/s"
        )
    );
    foreach ($shortcodes as $index => $shortcode) {
        if (strpos($text, $shortcode['check']) !== false) {
            $text = shortcode_replace($shortcode, $text);
        }
    }
    return $text;
}


function shortcode_replace($shortcode, $text) {
    $replacement = '';
    preg_match_all($shortcode['match'], $text, $matches);
    switch ($shortcode['type']) {
        case "link":
            foreach ($matches[4] as $index => $match) {
                $link     = $matches[2][$index];
                $linktext = $matches[4][$index];
                $replacement .= '<a href="' . $link . '">' . $linktext . '</a>';
                $text = preg_replace($shortcode['replace'], $replacement, $text);
            }
    }

    return $text;
}



echo shortcodes($text);

любая помощь приветствуется!


  • почему вы добавляете замену строки '$ replace .= ...'? 23.04.2014
  • считайте это $replacemant , 23.04.2014
  • ваша проблема, конечно, в том, что preg_match_all() находит все вхождения. поэтому он также заменяет первый 23.04.2014
  • @Alex Я отредактировал пост, чтобы переменная replace не смущала тебя. 23.04.2014
  • каждый раз, когда вы находите новую ссылку, все остальные ссылки автоматически обновляются. Лучшее решение — использовать strpos() и просто получить только «непроанализированную» часть строки. Я пробую решение прямо сейчас 23.04.2014
  • @seblaze, я понимаю, что ты имеешь в виду, так что все заменяется последним совпадением, т.н. хм решение было бы отличным. спасибо! 23.04.2014
  • Каков синтаксис ваших шорткодов, чтобы сделать что-то жирным? [bold text="make me bold"] или [bold]make me bold[/bold] или [b]make me bold[/b]? 23.04.2014

Ответы:


1

Была проблема в регулярном выражении, я изменил его. Также вам не нужен там preg_replace.

<?php
$text = 'Some text and some [link link="linkhref1" text="Text1"],[link link="linkhref2" text="Text2"]';


function shortcodes($text) {
    $shortcodes = array(
        'link' => array(
            "check" => "[link",
            "type" => "link",
            "match" => "#\[link(\s+)link\=\"([^\"]+)\"(\s+)text\=\"([^\"]+)\"\]#Ui",
            "replace" => "/\[link(.*?)\]/s"
        )
    );
    foreach ($shortcodes as $index => $shortcode) {
        if (strpos($text, $shortcode['check']) !== false) {
            $text = shortcode_replace($shortcode, $text);
        }
    }
    return $text;
}


function shortcode_replace($shortcode, $text) {
    $replace = '';
    preg_match_all($shortcode['match'], $text, $matches);
    switch ($shortcode['type']) {
        case "link":
            var_dump($matches);
            foreach ($matches[4] as $index => $match) {
                $link     = $matches[2][$index];
                $linktext = $matches[4][$index];
                $replace = '<a href="' . $link . '">' . $linktext . '</a>';
                $text = str_replace($matches[0][$index], $replace, $text);
            }
    }

    return $text;
}



echo shortcodes($text);
22.04.2014
  • спасибо! Я просто играл с str_replace вместо preg_replace 23.04.2014

  • 2

    Вот рабочая версия:

    <?php
    $text = 'Some text and some [link link="linkhref1" text="Text1"],[link link="linkhref2" text="Text2"]';
    
    
    function shortcodes($text) {
        $shortcodes = array(
            'link' => array(
                "check" => "[link",
                "type" => "link",
                "match" => "#\[link(.*?)link\=\"(.*?)\"(.*?)text\=\"(.*?)\"#",
                "replace" => "/\[link(.*?)\]/s"
            )
        );
        foreach ($shortcodes as $index => $shortcode) {
            if (strpos($text, $shortcode['check']) !== false) {
                $text = shortcode_replace($shortcode, $text);
            }
        }
        return $text;
    }
    
    
    function shortcode_replace($shortcode, $text) {
        $replace = '';
        preg_match_all($shortcode['match'], $text, $matches);
    
        switch ($shortcode['type']) {
            case "link":
                foreach ($matches[4] as $index => $match) {
                    $link     = $matches[2][$index];
                    $linktext = $matches[4][$index];
                    $replace .= '<a href="' . $link . '">' . $linktext . '</a>';
                    $whatToReplace = '[link link="'.$link.'" text="'.$linktext.'"]';
    
    
                    $text = str_replace($whatToReplace, $replace, $text);
                }
        }
    
        return $text;
    }
    
    
    
    echo shortcodes($text);
    

    Я не очень хорошо разбираюсь в RegExp, я модифицировал «совпадение», чтобы оно соответствовало всем ссылкам (с тем, что вы получили, это не так)

    Вам нужно указать именно [ссылка] для замены, а не все сразу. На мой взгляд, это правильный способ идентификации ссылки. Вы также можете идентифицировать ее с помощью strpos() (получив начало и конец строки) или посмотреть, где находится [ссылка начинается и первая].

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

    Надеюсь, это поможет вам

    22.04.2014
  • неплохо, но я не могу использовать его, так как есть много шорткодов, и я должен использовать совпадение 23.04.2014
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..