php
  • regex
  • preg-replace
  • replace
  • 2009-04-18 5 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-адресом. Это для системы рассылки новостей, в которой я хочу отслеживать, на что люди нажимали, поэтому URL-адрес будет «поддельным» URL-адресом, который будет перенаправлен на реальный URL после записи клика.

    ответ

    2

    Проблема в том, что ваша первая строка замены будет соответствовать второму шаблону поиска, эффективно перезаписывая первую заменяющую строку второй заменяющей строкой.

    Если вы не можете каким-либо образом отличить «модифицированные» ссылки от исходных, чтобы они не попадали под другое выражение (возможно, добавив дополнительное свойство HTML?), Я не думаю, что вы действительно можете решить эту проблему с одним вызовом preg_replace(). Одно из возможных решений (помимо дифференциации в регулярном выражении), которое приходит на ум, - использовать preg_match_all(), так как оно даст вам множество совпадений для работы. Возможно, вы, возможно, затем закодировали согласованные URL-адреса с URL-адресом отслеживания, выполнив итерацию по массиву и выполнив str_replace() по каждому совпадающему URL-адресу.

    +0

    Как бы вы использовали preg_match сделать замену? –

    +0

    К сожалению, забыл о том, что когда 1 писали мои 1-1 после того, как первоначально отредактирован свой пост, чтобы добавить потенциальный способ использования preg_match(), чтобы достичь того, чего вы хотите. Надеюсь, что это помогает. – hbw

    +0

    Кроме того, 1 случайно сказал preg_match(), когда на самом деле имел в виду preg_match_all 1() - жаль, что это было время, так как 1've использовали эти функции. – hbw

    1

    Я плохо разбираюсь в регулярных выражениях, но если вы делаете это, просто заменяете внешние URL (т. Е. Не являетесь частью вашего сайта/приложения) внутренним URL-адресом, который будет отслеживать клики и перенаправлять пользователя, тогда должно быть легко создать регулярное выражение, которое будет соответствовать только внешним URL-адресам.

    Итак, предположим, что ваш домен foo.com, вам просто нужно создать регулярное выражение, которое будет соответствовать только гиперссылке, которая не содержит URL-адреса, начиная с http://foo.com. Теперь, как я уже сказал, я очень плохо с регулярными выражениями, но вот мой лучший удар в нем:

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

    Edit: Если вы хотите отслеживать клик-thrus для внутренних 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 ,

    На втором проходе поиска, скрипт будет исследовать:

    <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.

    На третьем проходе поиска скрипт рассмотрит первые 2 (уже замененные) ссылки, пропустит их, а затем найдет соответствие с последней ссылкой в ​​информационном бюллетене.

    +0

    внутренний или внешний на самом деле не имеет значения для меня. 1 хочет заменить все ссылки, чтобы отслеживать все клики. –

    +0

    В этом случае вам просто нужно заменить http://foo.com с точным адресом страницы переадресации/отслеживания. – Calvin

    +0

    , что до сих пор не работает, если у вас есть 1 URL будет www.google.com, а другие собирается cnn.com. Каждая ссылка должна быть заменена уникальными другими ссылками. –

    1

    Я не знаю, если бы я понял это правильно. Но я написал следующий фрагмент: Регулярное выражение соответствует некоторым гиперссылкам. Затем он перебирает через результат и сравнивает текстовые узлы с ссылками гиперссылок. Когда текстовый узел находится в ссылке гиперссылки, он расширяет совпадения, вставляя ссылку на образец трекбэка с уникальным ключом.

    UPDATE отрывки находит все гиперссылок:

    1. найти ссылки
    2. построить трек назад ссылку
    3. найти положение каждой найденной ссылки (матчи [3]) и установить тег шаблона
    4. заменить templatetags ссылками trackback Каждая позиция ссылки уникальна.

    $ строка = '<h1> Newsletter Имя </h1 > < р > Lorem Ipsum боль сидеть Амет, consectetur adipiscing Элит. Донец lobortis, < язычок A HREF = "http://bar.com"> СЭД sollicitudin </с > dignissim, Lacus Dolor suscipit Sapien, < A HREF = "http://foo.com"> бар.кукуруза </ никакого реального воздействия от > температуры. Каждый разработчик стрелки членов. Он сидит крупные озера. самых больших фотографий < A HREF = "http://last.fm"> Laoreet бассейн </с >. </р > < < рассылка имя > H1/H1 > < р > Lorem Ipsum морковь, экологический томатный суп. До таблетки, Зарезервировано < A HREF = "http://bar.com"> но все равно </> от футбола, клиент получает потребитель Sapien < A HREF = "http://foo.com"> bar.com </ нет реального влияния от > температуры. Каждый разработчик стрелки членов. Он сидит крупные озера. самых больших фотографий < A HREF = "http://last.fm"> Laoreet бассейн </с >. </р > < < рассылка имя > H1/H1 > < р > Lorem Ipsum морковь, экологический томатный суп. До таблетки, Зарезервировано < A HREF = "http://bar.com"> но все равно </> от футбола, клиент получает потребитель Sapien < A HREF = "http://foo.com"> bar.com </ нет реального влияния от > температуры. Каждый разработчик стрелки членов. Он сидит крупные озера. самых больших фотографий < A HREF = "http://last.fm"> Laoreet бассейн </с >. </р > «;

    $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

    Это работает до вас есть 2 ссылки, которые идут в том же месте (место bar.com) в пределах одной и той же части текста, и все же вы хотите уникальные URL-адреса для каждой ссылки. Ваш массив будет содержать уникальные URL-адрес, но как заменить их в строке? –

    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); 
    

     Смежные вопросы

    • Нет связанных вопросов^_^