Is there un-wp_autop function?

The question:

I have a problem with WP that need your help. Some of my posts have content that was applied “wp_autop” filters already. This filter turned all double break lines into <p> tag. I want to the opposite thing: turn all <p> tag into double break lines.

Do you have any suggestions? Thank you.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

I just ran into this situation. Here is a function I used to undo wpautop. I might be missing something, but this is a good start:

function reverse_wpautop($s)
    //remove any new lines already in there
    $s = str_replace("n", "", $s);

    //remove all <p>
    $s = str_replace("<p>", "", $s);

    //replace <br /> with n
    $s = str_replace(array("<br />", "<br>", "<br/>"), "n", $s);

    //replace </p> with nn
    $s = str_replace("</p>", "nn", $s);       

    return $s;      

Method 2

I also needed a way to do this but wasn’t happy with any existing solutions so decided to make one. Hope it helps someone.


 * Replaces paragraph elements with double line-breaks.
 * This is the inverse behavior of the wpautop() function
 * found in WordPress which converts double line-breaks to
 * paragraphs. Handy when you want to undo whatever it did.
 * @see    wpautop()
 * @param  string $pee
 * @param  bool   $br (optional)
 * @return string
function fjarrett_unautop( $pee, $br = true ) {

    // Match plain <p> tags and their contents (ignore <p> tags with attributes)
    $matches = preg_match_all( '/<(p+)*(?:>(.*)</1>|s+/>)/m', $pee, $pees );

    if ( ! $matches ) {

        return $pee;


    $replace = array( "n" => '', "r" => '' );

    if ( $br ) {

        $replace['<br>']   = "rn";
        $replace['<br/>']  = "rn";
        $replace['<br />'] = "rn";


    foreach ( $pees[2] as $i => $tinkle ) {

        $replace[ $pees[0][ $i ] ] = $tinkle . "rnrn";


    return rtrim(
            array_keys( $replace ),
            array_values( $replace ),


Bonus: You could also potentially use this to determine if content has been altered by wpautop.

$is_wpautop = ( $content !== fjarrett_unautop( $content ) );

Method 3

The filter write not in the database, filter on frontend, when view the post or other content. You deactivate the filter and write a own filter for set your custom markup.

Method 4

There’s a built in function in WordPress, but it’s JavaScript only triggered when you switch from Visual to HTML in the post editor (and it’s really buggy if html is actually used though). If its just normal post content (not html code) then you can just edit each post, switch the editor back and forth, then save.

This is probably the most labor intensive, but safest, way.

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment