Function extension

The issue arises because str_replace() is replacing partial matches (like “POA” inside “POA (+)”). To fix this and ensure only exact matches are replaced, we can switch to using regular expressions with preg_replace().

Here’s a refined version of your function:

function auto_link_post_titles( $content, $post_id, $field ) {
    $excluded_ids = array(); 
    $excluded_field_names = array(); 
    
    if ( isset( $_GET['ntb'] ) || did_action( 'ninja_tables_loaded' ) ) {
        return $content;
    }

    if ( !in_array( $post_id, $excluded_ids ) && !in_array( $field['name'], $excluded_field_names ) ) {
        $desired_post_types = array( 'my_post_type', 'my_other_post_type' );

        $args = array(
            'post_type'      => $desired_post_types,
            'post_status'    => 'publish',
            'posts_per_page' => -1,
        );

        $posts = get_posts( $args );

        foreach ( $posts as $post ) {
            $post_title = esc_html( $post->post_title );
            $post_link  = esc_url( get_permalink( $post->ID ) );

            $link = '<a href="' . $post_link . '" target="_blank">' . $post_title . '</a>';

            // Escape special characters and match exact title
            $escaped_post_title = preg_quote($post_title, "https://wordpress.stackexchange.com/");
            $content = preg_replace('/\b' . $escaped_post_title . '\b/u', $link, $content);
        }   
    }

    return $content;
}

techhipbettruvabetnorabahisbahis forumutaraftarium24edueduedusedusedueduedueduseduedu