Как удалить дубликаты HTML-тегов из строки - php / regex - PullRequest
1 голос
/ 25 июня 2019

У меня есть несколько html-файлов, созданных плохим онлайн-редактором html. Пользователь выбирает любой текст и нажимает курсив, после чего текст будет вставлен в теги <em></em>.

Используя эти функции - иногда пользователь помещает какой-то текст курсивом, затем удаляет его, а затем снова меняет курсив.

Во многих случаях я получаю неверный HTML-код с дублирующимися тегами, как показано ниже:

Пример № 1:

Adding insult to injury, <em><em>Jennifer <a href="somelink">Aniston</a></em> had literally <a href="somelink2">zero clue</a> what was coming.</em>

Пример № 2:

Adding insult to injury, <em><em>Jennifer Aniston</em> had literally <a href="somelink2">zero clue</a> what was coming.</em>

Вопрос в том, как удалить дубликаты тегов - <em>-теги внутри других тегов <em> не нужны и должны быть удалены.

я написал код, но он не очень хорошо работал - красивое решение было бы с reg exp - я попробовал некоторое регулярное выражение, но не работало, поэтому я перешел к другому пути:

function repairDoubleTags($line = '', $rtag = 'em') {
    if(empty($line)) return false;

    if(!preg_match("#<".$rtag.">#", $line)) 
        return $line;

    $tmp = explode(" ", $line);
    //print_r($tmp);

    $lastposition = -1;
    $remove_next = 0;

    foreach($tmp as $nr => $word) {     
        //echo $word."\r\n";

        if(empty($word)) {
            unset($tmp[$nr]);
            continue;
        }

        if(preg_match("#<".$rtag.">#", $word)) {
            if($lastposition == -1) {
                $lastposition = $nr;
                //echo "----------------- ".$rtag." FOUND\r\n";
            }else {
                $tmp[$nr] = trim(preg_replace("#<".$rtag.">#", "", $tmp[$nr]));
                $remove_next = 1;
                $lastposition = -1;
                //echo "----------------- DOUBLE ".$rtag." FOUND AND REMOVED\r\n";
            }
        }

        if(preg_match("#</".$rtag.">#", $word)) {
            if($remove_next == 1) {
                $tmp[$nr] = trim(preg_replace("#</".$rtag.">#", "", $tmp[$nr]));
                $remove_next = 0;
                //echo "----------------- DOUBLE END ".$rtag." FOUND AND REMOVED\r\n";
            }else {
                $lastposition = -1;
            }
        }

        if(empty($tmp[$nr]))
            unset($tmp[$nr]);

    }

    //print_r($tmp);
    $line = join(' ', $tmp);
    //print_r($line);
    //exit;

    return $line;
}

Но этот код не работает, если HTML-код содержит более одного <em> - как пример, не работает, когда:

Adding insult to injury, <em><em>Jennifer Aniston</em> had literally <a href="somelink2">zero clue</a> what <em>was coming</em>.</em>

Любой regex эксперт для быстрого хорошего решения?

Спасибо!

1 Ответ

0 голосов
/ 25 июня 2019

Немного сложно догадаться, что может быть другим недопустимым <em>, который у нас может быть здесь, но если вы хотите изучить опцию регулярного выражения, мы можем начать с выражения, похожего на:

(?=<em><em>)(<em>)(.*?)(<\/em>)

и сделайте замену с $2.Это было бы просто примером, и выражение, несомненно, склонно к провалу.

Если бы у нас могли быть другие недопустимые теги, кроме em, мы бы просто перебрали выражение и сделали замены.

Тест

$re = '/(?=<em><em>)(<em>)(.*?)(<\/em>)/m';
$str = 'Adding insult to injury, <em><em>Jennifer <a href="somelink">Aniston</a></em> had literally <a href="somelink2">zero clue</a> what was coming.</em>

Adding insult to injury, <em><em>Jennifer Aniston</em> had literally <a href="somelink2">zero clue</a> what was coming.</em>
Adding insult to injury, <em><em>Jennifer Aniston</em> had literally <a href="somelink2">zero clue</a> what was coming.</em>

';
$subst = '$2';

$result = preg_replace($re, $subst, $str);

echo $result;

Дополнительную информацию см. В демоверсии.

Вывод

Adding insult to injury, <em>Jennifer <a href="somelink">Aniston</a> had literally <a href="somelink2">zero clue</a> what was coming.</em>

Adding insult to injury, <em>Jennifer Aniston had literally <a href="somelink2">zero clue</a> what was coming.</em>
Adding insult to injury, <em>Jennifer Aniston had literally <a href="somelink2">zero clue</a> what was coming.</em>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...