У меня есть начальная строка с различными текстами между тегами в нем, и
Строка может содержать вложенные теги.
Я хочу «удалить» строку в соответствии со следующими правилами:
1) последняя строка
не отличается от исходного, за исключением добавления или удаления некоторых тегов.
2) В последней строке каждый фрагмент текста заключен в ближайшую пару
тегов, которые заключены в исходную строку. Если есть несколько одинаково близких пар,
результат в неопределенном (но 3) никакой фрагмент текста не получает новые теги в последней строке).
Таким образом,
[a]text1[/a]text2[b]text3[c]text4[/c]text5[/b]
[e]text6[f]text7[/e]text8[/f]
должен стать
[a]text1[/a]text2[b]text3[/b][c]text4[/c][b]text5[/b]
[e]text6[/e]...[f]text8[/f]
где …
может быть любой из text7
, [e]text7[/e]
или же [f]text7[/f]
,
Есть ли регулярное выражение (например, рекурсивное регулярное выражение PCRE в PHP), которое делает это?
метод
Выполнить 3 замены:
Найдите закрывающий тег с последующим другим закрывающим тегом ==> вставьте открывающий тег для второго. Пример:
[/b]text[/c] ==> [/b][c]text[/c]
Найдите открывающий тег, за которым следует тег, который не является закрывающим тегом, соответствующим тому, который он только что нашел ==> вставьте закрывающий тег. Пример:
[a]text[b] ==> [a]text[/a][b]
[a]text[/b] ==> [a]text[/a][/b]
(Исправление к 2). Ищите 2 последовательных закрывающих тега ==> удалите второй. Пример:
[a]text[/a][/b] ==> [a]text[/a]
Код
$patterns = array ('#(\[/\w++])([^[]++\[/(\w++)])#',
'#\[(\w++)][^[]*+(?!\[/\1)#',
'#(\[/(\w++)])\[/\w++]#');
$replace = array ('\1[\3]\2',
'\0[/\1]',
'\1');
$string = "[a]text1[/a]text2[b]text3[c]text4[/c]text5[/b]\n[e]text6[f]text7[/e]text8[/f]";
$result = preg_replace($patterns, $replace, $string);
Выход
[a]text1[/a]text2[b]text3[/b][c]text4[/c][b]text5[/b]
[e]text6[/e][f]text7[/f][f]text8[/f]
Других решений пока нет …