2

私は次のものを持っています:

$reg[0] = '`<a(\s[^>]*)href="([^"]*)"([^>]*)>`si';
$reg[1] = '`<a(\s[^>]*)href="([^"]*)"([^>]*)>`si';
$replace[0] = '<a$1href="http://www.yahoo.com"$3>';
$replace[1] = '<a$1href="http://www.live.com"$3>';
$string = 'Test <a href="http://www.google.com">Google!!</a>Test <a href="http://www.google.com">Google!!2</a>Test';
echo preg_replace($reg, $replace, $string);

結果は次のとおりです。

Test <a href="http://www.live.com">Google!!</a>Test <a href="http://www.live.com">Google!!2</a>Test

私は(最初のリンクにある違い)で終わることを目指しています:

Test <a href="http://www.yahoo.com">Google!!</a>Test <a href="http://www.live.com">Google!!2</a>Test

アイデアは、文字列内のリンク内の各 URL を一意の他の URL に置き換えることです。これは、人々が何をクリックしたかを追跡したいニュースレター システム用であるため、URL は「偽の」URL になり、クリックが記録された後に実際の URL にリダイレクトされます。

4

4 に答える 4

2

問題は、最初の置換文字列が 2 番目の検索パターンと一致し、最初の置換文字列を 2 番目の置換文字列で効果的に上書きすることです。

「変更された」リンクを元のリンクと区別して、他の式に引っかからないようにすることができない限り (おそらく、余分な HTML プロパティを追加することでしょうか?)、1 回のpreg_replace()呼び出しでこれを本当に解決できるとは思いません。 . 考えられる解決策の 1 つ (正規表現の区別は別として) は、 を使用preg_match_all()することです。これにより、使用する一致の配列が得られるからです。配列を繰り返し処理し、一致した URL ごとに a を実行することで、一致した URL をトラッキング URL でエンコードすることができstr_replace()ます。

于 2009-04-18T07:34:21.140 に答える
1

私がそれを正しく理解していたかどうかはわかりません。しかし、私は次のスニペットを書きました: 正規表現はいくつかのハイパーリンクに一致します。次に、結果をループして、テキスト ノードをハイパーリンク参照と比較します。ハイパーリンク参照でテキスト ノードが見つかると、一意のキーを持つトラックバック サンプル リンクを挿入することで一致を拡張します。

UPDATE スニペットはすべてのハイパーリンクを見つけます:

  1. リンクを見つける
  2. トラックバックリンクを作成する
  3. 見つかった各リンクの位置を見つけて (matches[3])、テンプレート タグを設定します。
  4. テンプレートタグをトラックバック リンクに置き換えます 各リンクの位置は一意です。

$string = '<h1>ニュースレター名</h1> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec lobortis、ligula <a href="http://bar.com">sed sollicitudin</a> dignissim、lacus dolor suscipit sapien、<a href="http://foo.com">bar.com</ a> ipsum ligula non tortor. Quisque sagittis sodales elit. Mauris dictum blandit lacus. Mauris consequat <a href="http://last.fm">laoreet lacus</a>.</p> <h1>ニュースレター名</h1> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec lobortis、ligula <a href="http://bar.com">sed sollicitudin</a> dignissim、lacus dolor suscipit sapien、<a href="http://foo.com">bar.com</ a> ipsum ligula non tortor. Quisque sagittis sodales elit. Mauris dictum blandit lacus. Mauris consequat <a href="http://last.fm">laoreet lacus</a>.</p> <h1>ニュースレター名</h1> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec lobortis、ligula <a href="http://bar.com">sed sollicitudin</a> dignissim、lacus dolor suscipit sapien、<a href="http://foo.com">bar.com</ a> ipsum ligula non tortor. Quisque sagittis sodales elit. Mauris dictum blandit lacus. Mauris consequat <a href="http://last.fm">laoreet lacus</a>.</p> '; Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec lobortis、ligula <a href="http://bar.com">sed sollicitudin</a> dignissim、lacus dolor suscipit sapien、<a href="http://foo.com">bar.com</ a> ipsum ligula non tortor. Quisque sagittis sodales elit. Mauris dictum blandit lacus. Mauris consequat <a href="http://last.fm">laoreet lacus</a>.</p> '; Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec lobortis、ligula <a href="http://bar.com">sed sollicitudin</a> dignissim、lacus dolor suscipit sapien、<a href="http://foo.com">bar.com</ a> ipsum ligula non tortor. Quisque sagittis sodales elit. Mauris dictum blandit lacus. Mauris consequat <a href="http://last.fm">laoreet lacus</a>.</p> ';

$regex = '<[^>]+>(.*)<\/[^>]+>';
preg_match_all("'<a\s+href=\"(.*)\"\s*>(.*)<\/[^>]+>'U",$string,$matches);


$uniqueURL = 'http://www.yourdomain.com/trackback.php?id=';

foreach($matches[2] as $k2 => $m2){
    foreach($matches[1] as $k1 => $m1){
        if(stristr($m1, $m2)){
                $uniq = $uniqueURL.md5($matches[0][$k2])."_".rand(1000,9999);
                $matches[3][$k1] = $uniq."&refLink=".$m1;
        }
    }
}


foreach($matches[3] as $key => $val) {

    $startAt = strpos($string, $matches[1][$key]);
    $endAt= $startAt + strlen($matches[1][$key]);

    $strBefore = substr($string,0, $startAt);
    $strAfter = substr($string,$endAt);

    $string = $strBefore . "@@@$key@@@" .$strAfter;

}
foreach($matches[3] as $key => $val) {
        $string = str_replace("@@@$key@@@",$matches[3][$key] ,$string);
}
print "<pre>";
echo $string;
于 2009-04-19T09:43:35.267 に答える
1

私は正規表現が苦手ですが、外部 URL (つまり、サイト/アプリケーションの一部ではない) を、クリックスルーを追跡してユーザーをリダイレクトする内部 URL に置き換えるだけであれば、簡単なはずです。外部 URL のみに一致する正規表現を作成します。

ドメインが であるとしましょうfoo.com。次に、で始まる URL を含まないハイパーリンクにのみ一致する正規表現を作成する必要がありますhttp://foo.com。さて、私が言ったように、私は正規表現がかなり苦手ですが、これが私の最善の試みです:

$reg[0] = '`<a(\s[^>]*)href="(?!http://foo.com)([^"]*)"([^>]*)>`si';

編集: 内部 URL へのクリックスルーも追跡する場合http://foo.comは、リダイレクト/追跡ページの URL に置き換えますhttp://foo.com/out.php

私が話していることを示すためだけに、シナリオの例を見ていきます。以下のニュースレターがあるとします。

<h1>Newsletter Name</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec lobortis,
ligula <a href="http://bar.com">sed sollicitudin</a> dignissim, lacus dolor
suscipit sapien, <a href="http://foo.com">eget auctor</a> ipsum ligula
non tortor. Quisque sagittis sodales elit. Mauris dictum blandit lacus.
Mauris consequat <a href="http://last.fm">laoreet lacus</a>.</p>

この演習では、検索パターンは次のようになります。

// Only match links that don't begin with: http://foo.com/out.php
`<a(\s[^>]*)href="(?!http://foo.com/out\.php)([^"]*)"([^>]*)>`si

この正規表現は、次の 3 つの部分に分けることができます。

  1. <a(\s[^>]*)href="
  2. (?!http://foo.com/out\.php)([^"]*)
  3. "([^>]*)>

検索の最初のパスで、スクリプトは以下を調べます。

<a href="http://bar.com">

このリンクは正規表現の 3 つのコンポーネントすべてを満たすため、URL はデータベースに保存され、http://foo.com/out.php?id=1.

検索の 2 回目のパスで、スクリプトは以下を調べます。

<a href="http://foo.com/out.php?id=1">

このリンクは 1 と 3 に一致しますが、2 には一致しません。したがって、検索は次のリンクに進みます。

<a href="http://foo.com">

このリンクは正規表現の 3 つのコンポーネントすべてを満たすため、URL はデータベースに保存され、http://foo.com/out.php?id=2.

検索の 3 回目のパスで、スクリプトは最初の 2 つの (既に置換されている) リンクを調べてスキップし、ニュースレターの最後のリンクと一致するものを見つけます。

于 2009-04-18T08:46:27.957 に答える
0

その場で関数を作成できる PHP 5.3 までは、create_function (私は嫌いです) またはヘルパー クラスのいずれかを使用する必要がありました。

/**
 * For retrieving a new string from a list.
 */
class StringRotation {
    var $i = -1;
    var $strings = array();

    function addString($string) {
        $this->strings[] = $string;
    }

    /**
     * Use sprintf to produce result string
     * Rotates forward
     * @param array $params the string params to insert
     * @return string
     * @uses StringRotation::getNext()
     */
    function parseString($params) {
        $string = $this->getNext();
        array_unshift($params, $string);
        return call_user_func_array('sprintf', $params);
    }

    function getNext() {
        $this->i++;
        $t = count($this->strings);
        if ($this->i > $t) {
            $this->i = 0;
        }
        return $this->strings[$this->i];
    }

    function resetPointer() {
        $this->i = -1;
    }
}

$reg = '`<a(\s[^>]*)href="([^"]*)"([^>]*)>`si';
$replaceLinks[0] = '<a%2$shref="http://www.yahoo.com"%4$s>';
$replaceLinks[1] = '<a%2$shref="http://www.live.com"%4$s>';

$string = 'Test <a href="http://www.google.com">Google!!</a>Test <a href="http://www.google.com">Google!!2</a>Test';

$linkReplace = new StringRotation();
foreach ($replaceLinks as $replaceLink) {
    $linkReplace->addString($replaceLink);
}

echo preg_replace_callback($reg, array($linkReplace, 'parseString'), $string);
于 2009-04-19T20:56:26.493 に答える