php string - Come imitare comportamento di collegamento automatico overflow dello stack




matches preg (6)

Con PHP come posso imitare il comportamento di collegamento automatico di (che BTW è incredibilmente interessante)?

Ad esempio, il seguente URL:

http://www..com/questions/1925455/how-to-mimic--auto-link-behavior

È convertito in questo:

<a title="how to mimic  auto link behavior" rel="nofollow" href="http://www..com/questions/1925455/how-to-mimic--auto-link-behavior">.com/questions/1925455/…</a>

In questo caso non mi interessa davvero l'attributo title .

E questo:

http://pt.php.net/manual/en/function.base-convert.php#52450

È convertito in questo:

<a rel="nofollow" href="http://pt.php.net/manual/en/function.base-convert.php#52450">pt.php.net/manual/en/…</a>

Come posso creare una funzione simile in PHP?

PS: Controlla i miei commenti su questa domanda per ulteriori esempi e comportamenti.


Answers

Vedi Regex (espressione regolare) per abbinare un URL :

https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?

Esempio PHP: collega automaticamente il testo interno dell'URL.

$text = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', '<a href="$1">$1</a>', $text);

Questo convertirà la stringa campione in quello che stai cercando. Ho omesso il title dato che proviene da una fonte diversa rispetto a un semplice URL indipendente e hai detto che non era importante.

<?php
$urlInput="http://www..com/questions/1925455/how-to-mimic--auto-link-behavior";
preg_match('@http://(?:www\.)?(\S+/)\S*(?:\s|$)@i', $urlInput, $matches);
print('<a rel="nofollow" href="' . trim($matches[0]) . '">' . $matches[1] . '...</a>');
?>

Estendere quanto necessario per eseguire la scansione del testo.

Se vuoi abbinare solo un certo numero di elementi del percorso URL, usa questo RE:

'@http://(?:www\.)?((?:\S+?/){1,3})\S*(?:\s|$)@i'

Questo estrarrà fino a 3 elementi di percorso (l'host e fino a due directory). È possibile variare il limite superiore in {1,3} per definire il numero massimo di elementi del percorso che si desidera.

Modificato il finale \S per consentire zero corrispondenze.


Prova questo. Il pattern regex di corrispondenza dell'URL proviene da Daring Fireball .

/**
 * Replace links in text with html links
 *
 * @param  string $text
 * @return string
 */
function auto_link_text($text)
{
   // a more readably-formatted version of the pattern is on http://daringfireball.net/2010/07/improved_regex_for_matching_urls
   $pattern  = '(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’]))';

   $callback = create_function('$matches', '
       $url       = array_shift($matches);
       $url_parts = parse_url($url);

       $text = parse_url($url, PHP_URL_HOST) . parse_url($url, PHP_URL_PATH);
       $text = preg_replace("/^www./", "", $text);

       $last = -(strlen(strrchr($text, "/"))) + 1;
       if ($last < 0) {
           $text = substr($text, 0, $last) . "&hellip;";
       }

       return sprintf(\'<a rel="nofollow" href="%s">%s</a>\', $url, $text);
   ');

   return preg_replace_callback($pattern, $callback, $text);
}

Testo di input:

This is my text.  I wonder if you know about asking questions on :
 Check This out http://www..com/questions/1925455/how-to-mimic--auto-link-behavior

 Also, base_convert php function?
http://pt.php.net/manual/en/function.base-convert.php#52450

http://pt.php.net/manual/en/function.base-convert.php?wtf=hehe#52450

Testo di output:

This is my text.  I wonder if you know about asking questions on :
 Check This out <a rel="nofollow" href="http://www..com/questions/1925455/how-to-mimic--auto-link-behavior">.com/questions/1925455/&hellip;</a>

 Also, base_convert php function?
<a rel="nofollow" href="http://pt.php.net/manual/en/function.base-convert.php#52450">pt.php.net/manual/en/&hellip;</a>

<a rel="nofollow" href="http://pt.php.net/manual/en/function.base-convert.php?wtf=hehe#52450">pt.php.net/manual/en/&hellip;</a>

Basato piuttosto sulla risposta di Kevin Brock, ma consente parametri configurabili (profondità della cartella e lunghezza dell'URL) e accetta URL senza barre finali:

$url = 'http://www..com/questions/1925455/how-to-mimic--auto-link-behavior';
$output = '';
$params = array (
    'length' => 10,
    'depth' => 2,
);
preg_match ('@http://(?:www\.)?([^/?# ]+)(/\S+)?(?=\s|$)@i', $url, $matches);
if (isset ($matches[2]))
{
    $parts = explode('/', substr($matches[2], 1));
    if (count($parts) > $params['depth'] && strlen($matches[1].$matches[2]) > $params['length'])
        $output = $matches[1].'/'.implode('/', array_slice($parts, 0, 2)).'/...';
    else
        $output = $matches[1].$matches[2];
}
else
    $output = $matches[1];

echo '<a href="'.$matches[0].'">'.$output.'</a>';

Spero che questo ti aiuti


Questo si basa sulla stessa espressione regolare di daringfireball.net , ma aggiunge un po 'più logica dell'esempio di Eric Coleman, così come la configurazione per la massima profondità dell'URL (SO sembra essere 50), massima profondità del percorso quando l'URL viene troncato (SO sembra essere 2), e carattere ellissi ( &hellip; ).

Per quanto ne so, questo replica tutte le funzionalità di riscrittura degli URL SO, almeno per quanto discusso finora nei commenti e nelle risposte.

function auto_link_text($text) {
    $pattern  = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#';
    return preg_replace_callback($pattern, 'auto_link_text_callback', $text);
}

function auto_link_text_callback($matches) {
    $max_url_length = 50;
    $max_depth_if_over_length = 2;
    $ellipsis = '&hellip;';

    $url_full = $matches[0];
    $url_short = '';

    if (strlen($url_full) > $max_url_length) {
        $parts = parse_url($url_full);
        $url_short = $parts['scheme'] . '://' . preg_replace('/^www\./', '', $parts['host']) . '/';

        $path_components = explode('/', trim($parts['path'], '/'));
        foreach ($path_components as $dir) {
            $url_string_components[] = $dir . '/';
        }

        if (!empty($parts['query'])) {
            $url_string_components[] = '?' . $parts['query'];
        }

        if (!empty($parts['fragment'])) {
            $url_string_components[] = '#' . $parts['fragment'];
        }

        for ($k = 0; $k < count($url_string_components); $k++) {
            $curr_component = $url_string_components[$k];
            if ($k >= $max_depth_if_over_length || strlen($url_short) + strlen($curr_component) > $max_url_length) {
                if ($k == 0 && strlen($url_short) < $max_url_length) {
                    // Always show a portion of first directory
                    $url_short .= substr($curr_component, 0, $max_url_length - strlen($url_short));
                }
                $url_short .= $ellipsis;
                break;
            }
            $url_short .= $curr_component;
        }

    } else {
        $url_short = $url_full;
    }

    return "<a rel=\"nofollow\" href=\"$url_full\">$url_short</a>";
}

Esempio di input:

This is my text.  I wonder if you know about asking questions on :
Check This out http://www..com/questions/1925455/how-to-mimic--auto-link-behavior

Also, base_convert php function?
http://pt.php.net/manual/en/function.base-convert.php#52450

http://pt.php.net/manual/en/function.base-convert.php?wtf=hehe#52450

http://a.b/c/d/e/f/test

and http://a.b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/z/y/w/z/test

Uscita di esempio:

This is my text.  I wonder if you know about asking questions on :
Check This out <a rel="nofollow" href="http://www..com/questions/1925455/how-to-mimic--auto-link-behavior">http://.com/questions/1925455/&hellip;</a> 

Also, base_convert php function?
<a rel="nofollow" href="http://pt.php.net/manual/en/function.base-convert.php#52450">http://pt.php.net/manual/en/&hellip;</a> 

<a rel="nofollow" href="http://pt.php.net/manual/en/function.base-convert.php?wtf=hehe#52450">http://pt.php.net/manual/en/&hellip;</a> 

<a rel="nofollow" href="http://a.b/c/d/e/f/test">http://a.b/c/d/e/f/test</a> 

and <a rel="nofollow" href="http://a.b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/z/y/w/z/test">http://a.b/c/d/&hellip;</a>

RegEx per il titolo:

(?i).*?<i>([^<]*).*               [ ] g  [x] s  [ ] m  [ ] i

RegEx per il collegamento:

(?i).*?href="([^"]*).*            [ ] g  [x] s  [ ] m  [ ] i

In qualche modo la casella di controllo non sensibile al maiuscolo / minuscolo sembra rotta. Fortunatamente puoi sostituire con (?i) , che funziona bene.

Ecco un simpatico strumento web2.0-ish per testare le espressioni regolari con: RegExr . Ma per qualche ragione è ancora beta. ;-)





php regex string