2

私は次のことを行うスクリプトを書き込もうとしていました。

  1. ファイルまたはデータベースからコンテンツを読み取る
  2. コンテンツからすべてのアンカータグを抽出します
  3. すべてのリンクをスキャンし、許可されているリンク(ソーシャルネットワーク、検索エンジン、または権限ドメインへのリンクなど)を保持し、コンテンツ(アンカーテキスト)を保持しながら残りを削除します。

内容の例:

<p><a rel="nofollow" href="http://www.test.com/tyest">test1</a></p>
<p><a href="http://google.com">google</a></p>
<p><a title="This is just a check" href="http://www.check.com">check</a></p>
<p><a rel="nofollow" href="http://www.ip.com">http://www.ip.com</a></p>

許可されたドメイン:

google.com
msn.com
ip.com

必要な出力:

<p>test1</p>
<p><a href="http://google.com">google</a></p>
<p>check</p>
<p><a rel="nofollow" href="http://www.ip.com">http://www.ip.com</a></p>

制限:

  1. アンカータグは特定のルールに従わず、rel、title、descritionプロパティを任意の順序で含めることができます。
  2. アンカーテキスト自体もリンクできます。例:リンクが許可されていない場合でも保持する必要があるhttp://google.com 。

私は宿題をして、オンラインで利用できるヘルプと一緒に別の正規表現を使用して最初の作業を開始するための簡単なベアレベルのスクリプトを書いてみましたが、成功しませんでした。これが私のコードです:

// sample input
$comment = '<p><a rel="nofollow" href="http://www.1google.com/tyest">test with no http</a></p>
                <p><a rel="nofollow" href="http://google.com">just a domain name</a></p>
                <p><a rel="nofollow" href="http://www.g1gle.com">check</a></p>
                <p><a rel="nofollow" href="http://www.ip.com">http://www.ip.com</a></p>
                <p><a rel="nofollow" href="http://osamashabrez.com">http://testx.osamashabrez.com</a></p>
                <p><a rel="nofollow" href="http://www.subchalega.com">http://www.subchalega.com</a></p>
                <p><a rel="nofollow" href="http://www.letscheck.com">http://www.letscheck.com</a></p>
                <p><a rel="nofollow" href="http://www.google.com/osama/here/">http://www.google.com</a></p>
                <p><a rel="nofollow" description="testing" title="google" href="http://www.google.com/last/">laaaaaaaa</a></p><h1>Header one</h1>
                <p><a rel="nofollow" href="http://domain1.com">http://testx.osamashabrez.com</a></p>';

// add http to the domain name if not already present
function addhttp($url) {
    if (!preg_match('~^(?:f|ht)tps?://~i', $url)) {
        $url = 'http://' . $url;
    }
    return $url;
}

// removed deep links to match with the allowed URLS 
function removeDeepLinks($url) {
    $pos = strrpos ( $url, '.com' );
    if ( $pos !== false )
        return substr( $url, 6, $pos-2 );
    return $url;
}
// allowed domains fetched from the db
$domains = "http://osamashabrez.com\rhttp://google.com\rwordpress.org\rabc.com";
$domains = preg_split( "~\r~", $domains, -1, PREG_SPLIT_NO_EMPTY );
// adding http if not already present
// will be done one when data will be inserted
foreach ( $domains as $key => $domain ) { $domains[$key] = addhttp($domain); }
// remove this and sky will fall on your head :D
sort( $domains );
print_r ( $domains );
// regex to extract href="xyz.com" link as we can not use any other option
// due to the uncertainity of data passed to this script
$regex = '/(href=".*?")/is';
if ($c=preg_match_all ($regex, $comment, $matches)) {
    $matches = $matches[1];
    foreach ( $matches as $key => $url ) {
        // remove deep links for matching
        $matches[$key] = removeDeepLinks($url);
    }
    print_r($matches);
    foreach( $matches as $key => $url ) {
        // if domain is not allowed
        if ( !array_search( $url, $domains ) ) {
            // find position of URL
            $pos_url     = strrpos( $comment, $url );
            // fint the starting position of anchor tag
            $pos_a_start = strrpos(substr($comment, 0, $pos_url), '<a ');
            // fint the end
            $pos_a_end   = strpos($comment, '</a>',$pos_url);
            // extract the whole anchor tag
            $anchor_tag  = substr($comment, $pos_a_start, $pos_a_end - $pos_a_start + 4);
            echo "URL:\t" .$url . "\r";
            echo "Anchor Tag:\t{$anchor_tag}\r";
            echo "POS START :: END:\t{$pos_a_start}::{$pos_a_end}\r";


            // something weired goes where commenting this line works but only the opening
            // tags are removed from the text
            // the code does work with some data inputs and does not work with a few others
            $comment = substr($comment, 0, $pos_a_end) . substr($comment, $pos_a_end+4);
            // removing opening tags
            $opening_tag = substr( $anchor_tag, 0, strpos($anchor_tag, '>') +1 );
            $comment = str_replace($opening_tag, '', $comment);
        }
    }
}
echo $comment;

上記のコードは、いくつかのデータ入力と他のデータ入力で動作しています。ヘルプ、動作するコード例、または提供されたコードのレビューを取得したいと思います。また、作業を行うためのより良い方法があるかどうかについても言及してください。どんな助けでも大歓迎です。

ありがとう

4

1 に答える 1

1

このタスクには、DOMパーサーの方が適しています。

次のような多くのオプションがあります。

QueryPathを使用した例を次に示します。

$qp = qp($html)
foreach ($qp->find('a') as $link) {
    $href = $link->attr('href');
    // Get the host domain
    $host = parse_url($href, PHP_URL_HOST);
    // Check our allowed hosts
    if (!in_array($host, $allowedHosts) {
        // Replace the links HTML with just its text
        $link->html($link->text());
    }
}
// Echo our result
echo $query->top()->html();

(テストされていませんが、いくつかの変更を加えることで機能するはずです。)

于 2012-07-07T22:34:44.333 に答える