php
  • regex
  • preg-replace
  • replace
  • 2009-04-18 82 views 2 likes 
    2

    我有以下幾點:如何用一個唯一的URL替換字符串中的每個URL?

    $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。這是一個通訊系統,我想跟蹤用戶點擊的內容,因此這個網址將是一個「假」的網址,在記錄點擊後他們將被重定向到真實的網址。

    回答

    2

    問題是您的第一個替換字符串將與第二個搜索模式匹配,從而有效地用第二個替換字符串覆蓋第一個替換字符串。

    除非你能以某種方式區分「修改」的鏈接和原來的鏈接,以便它們不會被其他表達式所捕獲(可能通過添加額外的HTML屬性?),我認爲你不能真正解決這個問題與一個preg_replace()呼叫。想到的一個可能的解決方案(除了正則表達式的區別)將使用preg_match_all(),因爲它會給你一組匹配的工作。您可以通過遍歷數組並在每個匹配的URL上運行str_replace(),然後使用跟蹤網址對匹配的網址進行編碼。

    +0

    你會如何使用的preg_match做更換? – 2009-04-18 07:45:56

    +0

    對不起,忘了這一點,當1寫我的1-1之後開始編輯我的職務,以增加使用的preg_match()來實現你想要的東西的一種潛在方式。希望它能幫助。 – hbw 2009-04-18 07:47:17

    +0

    此外,1一不小心說的preg_match()時,實際上意味着preg_match_all 1() - 比較遺憾的是,它已經有一段時間,因爲1've使用這些功能。 – hbw 2009-04-18 07:52:07

    1

    我不擅長用正則表達式,但如果你正在做的是隻是一個內部URL更換外部URL(即不是您的網站/應用程序的一部分),將跟蹤點擊貫穿線和重定向用戶,然後應該很容易構建一個只匹配外部URL的正則表達式。

    假設你的域名爲foo.com,那麼你只需要創建一個正則表達式,它只會匹配一個不包含以http://foo.com開頭的URL的超鏈接。現在,正如我所說,我除了正規很糟糕,但這裏是在我最好的刺:

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

    編輯: 如果你想跟蹤點擊貫穿線到內部URL爲好,然後只需更換http://foo.com與您的重定向/跟蹤頁面的網址,例如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

    在搜索的第二次,該腳本將檢查:

    <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個(已替換)鏈接,跳過它們,然後找到與通訊中最後一個鏈接匹配的鏈接。

    1

    我不知道,如果我理解正確的話。但我寫了下面的代碼片段: 正則表達式匹配一些超鏈接。然後通過結果循環 並將文本節點與超鏈接引用進行比較。 當在超鏈接引用中找到文本節點時,它通過插入具有唯一鍵的引用示例鏈接來擴展匹配。

    UPDATE 的片段找到的所有超鏈接:

    1. 鏈接找到
    2. 建立跟蹤反向鏈接的每個發現鏈接的
    3. 查找位置(匹配[3])和 設置模板標籤
    4. 通過引用鏈接替換模板標籤 每個鏈接位置都是唯一的。

    $字符串='<H1>簡報名稱</H1 > <p> Lorem存有悲坐阿梅德,consectetur adipiscing ELIT。 Donec lobortis, ligula < a se sollicitudin </a > dignissim,lacus dolor suscipit sapien,< a href =「http://foo.com」> bar。玉米</ 從>溫度無實質影響。每個顯影劑箭頭成員。它坐最大的湖泊。 最大攝影< A HREF = 「http://last.fm」> Laoreet池< /從>。 </P > < <名稱通訊> H1/H1 > <p> Lorem存有胡蘿蔔,生態番茄湯。直到丸, 保留< A HREF = 「http://bar.com」>但是愛護足球</>,客戶收到消費者 SAPIEN < A HREF = 「http://foo.com」> bar.com從>溫度</ 無實質影響。每個顯影劑箭頭成員。它坐最大的湖泊。 最大攝影< A HREF = 「http://last.fm」> Laoreet池< /從>。 </P > < <名稱通訊> H1/H1 > <p> Lorem存有胡蘿蔔,生態番茄湯。直到丸, 保留< A HREF = 「http://bar.com」>但是愛護足球</>,客戶收到消費者 SAPIEN < A HREF = 「http://foo.com」> bar.com從>溫度</ 無實質影響。每個顯影劑箭頭成員。它坐最大的湖泊。 最大攝影< A HREF = 「http://last.fm」> Laoreet池< /從>。 </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 . "@@@[email protected]@@" .$strAfter; 
    
    } 
    foreach($matches[3] as $key => $val) { 
         $string = str_replace("@@@[email protected]@@",$matches[3][$key] ,$string); 
    } 
    print "<pre>"; 
    echo $string; 
    
    0

    直到PHP 5.3你可以當場創建一個功能,您可以選擇使用create_function(其中1恨)或輔助類。

    /** 
    * 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); 
    
    相關問題