WordPress объединяет сообщения в этом формате:
<h2>Some header</h> <p>First paragraph of the post</p> <p>Second paragraph of the post</p> etc.
Чтобы получить мой классный стиль в первом абзаце (это одна из тех вещей, которые выглядят хорошо только экономно), мне нужно подключиться к функции get_posts, чтобы отфильтровать ее вывод с помощью preg_replace.
Цель состоит в том, чтобы получить приведенный выше код:
<h2>Some header</h> <p class="first">First paragraph of the post</p> <p>Second paragraph of the post</p>
У меня это до сих пор, но он даже не работает (ошибка: «preg_replace () [function.preg-replace]: Неизвестный модификатор ']'")
$output=preg_replace('<p[^>]*>', '<p class="first">', $content);
Я не могу использовать мета-селектор CSS3, потому что мне нужно поддерживать IE6, и я не могу применить мета-селектор первой строки (это тот, который поддерживает IE6) в родительском контейнере, потому что он попадет в H2 вместо первый П.
Возможно, вам будет проще и надежнее использовать парсер HTML, такой как этот . HTML, как известно, трудно анализировать достоверно (технически, невозможно) с помощью регулярных выражений, и синтаксический анализатор предоставит вам очень простое средство поиска интересующих вас узлов. На первой странице документа есть вкладка с надписью «Как изменить HTML-элементы ".
Две правильные возможности:
$("h2").next().addClass("first")
Неправильный путь
Конечно, чтобы ответить на вопрос, вот лучший способ, который я не могу придумать, чтобы сделать это с регулярным выражением. Хотя, я не рекомендую.
preg_replace('#(</h2>\s*<p[^>]*)>#im', '$1 class="first">', '<h2>Some header</h> <p>First paragraph of the post</p> <p>Second paragraph of the post</p> ');
Что мы делаем:
</h2>\s*
для соответствия закрывающим «h2» тегам и всем разрывам пробелов / строк; *<p[^>]*
для соответствия тегу «p» и его текущим атрибутам; Первый откат, о котором я могу думать, заключается в том, что он не обрабатывает случай, когда класс уже существует.
Из и, кстати, у вас <h2>...</h>
вместо <h2>...</h2>
. Я не знаю, это опечатка, но я так и думал. Замените в регулярном выражении соответственно, если это не так.
Проблема в том, что первый символ регулярного выражения в функции preg_*
принимается за разделитель модификатора. Вам нужно что-то вроде:
$output = preg_replace('~<p\b([^>]*)>~', '<p class="first" \1>', $content, 1);
Это также возвращает любые дополнительные атрибуты, которые могут иметь <p>
.
В целом, однако, это более чистое отношение к селекторам CSS и резервному обеспечению JS для IE.
EDIT: добавлен лимит замены и разрыв слов.
в этом конкретном случае регулярное решение будет довольно простым
echo preg_replace('~</h2>\s*<p~', "$0 class='first'", $html);
Прочитав ответы, некоторые из них будут работать, но у всех есть недостатки либо использования внешней библиотеки синтаксического анализа, либо, возможно, соответствия меток, отличных от тега P, а также соответствия его атрибутам.
Я закончил использование этого решения с функцией str_replace_once отсюда :
str_replace_once('<p>', '<p class="first">', $content);
Достаточно просто и работает так, как предполагалось. Вот полный фрагмент кода WordPress для фильтрации первого абзаца всякий раз, когда вызывается вызов the_content ():
add_filter('the_content', 'first_p_style'); function first_p_style($content) { $output=str_replace_once('<p>', '<p class="first">', $content); return ($output); }
Спасибо за ответы на все вопросы!