When I split a large post with , how can a search locate users to the correct page?

UPDATE: After I needed this myself, I reworked it completely.

The Goal

I wanted to point every get_permalink() call directly to the paged post page – without any exception. At least this is the function used by nearly every other function that needs to link somewhere, so it imo also is the most reliable.

What the plugin does

It jumps in when WP is fully loaded and adds an action/callback function to the the_post-hook. There it then checks the globals $numpages (holds the number of pages a post has) and $pages (holds the parts a post is splitted up by using <!--nextpost--> in the content). If the number of pages is not larger than 1, it aborts. Else it searches through the posts pages for the searched string. If it was found, then it sets the $link class property to the page link using _wp_link_page(). This link then gets attached inside the filters offered by get_permalink().

What for does it work?

It works for posts, pages & custom post types

The plugin

As everytime: Free for use. Grab it, use it. Have fun with it.

<?php
/**
 * Plugin Name: (#31913) Search Results - direct link to page
 */

add_action( 'wp', array( 'search_direct_page_links', 'init' ) );

class search_direct_page_links
{
    public static $instance;

    public static $s;

    public $link;

    public static function init()
    {
        is_null( self :: $instance ) AND self:: $instance = new self;
        return self :: $instance;
    }

    public function __construct()
    {
        if ( ! is_search() )
            return;

        is_null( self :: $s ) AND self :: $s = get_query_var( 's' );

        add_action( 'the_post', array( $this, 'is_paged' ) );
    }

    public function is_paged( $post )
    {
        global $numpages, $pages;

        // reset link:
        $this->link = get_permalink();

        // Remove filters attached from the last post
        foreach ( array( 'post_link', 'page_link', 'post_type_link' ) as $filter )
        {
            remove_filter( $filter, array( $this, 'alter_link' ) );
        }

        if ( 1 >= $numpages )
            return;

        $target = 1;
        foreach ( $pages as $i => $p )
        {
            if ( is_int( strpos( $p, self :: $s ) ) )
            {
                $target = absint( $i ) +1;

                // Get the link now, as _wp_link_page()
                // calls get_permalink() internally,
                // which would lead to an endless nested loop.
                $this->link = str_replace(
                     array( '<a href="', '">' )
                    ,''
                    ,_wp_link_page( $target )
                );
            }
        }

        if ( 1 < $target )
        {
            add_filter( 'post_link', array( $this, 'alter_link' ), 10, 3 );
            add_filter( 'page_link', array( $this, 'alter_link' ), 10, 3 );
            add_filter( 'post_type_link', array( $this, 'alter_link' ), 10, 4 );
        }
    }

    public function alter_link( $permalink, $post, $leavename, $sample )
    {
        return $this->link;
    }
}