Preg_replace или preg_replace_callback? - PullRequest
       5

Preg_replace или preg_replace_callback?

3 голосов
/ 01 сентября 2011

У меня есть ссылки на некоторые страницы, которые используют старую систему, такую ​​как:

<a href='/app/?query=stuff_is_here'>This is a link</a>

Они должны быть преобразованы в новую систему, такую ​​как:

<a href='/newapp/?q=stuff+is+here'>This is a link</a>

Я могу использовать preg_replace t0, чтобы изменить то, что мне нужно, но мне также нужно заменить подчеркивания в запросе на + вместо. Мой текущий код:

//$content is the page html
$content = preg_replace('#(href)="http://www.site.com/app/?query=([^:"]*)(?:")#','$1="http://www.site.com/newapp/?q=$2"',$content);

Я хочу запустить str_replace для переменной $ 2, поэтому я попытался использовать preg_replace_callback и не смог заставить его работать. Что мне делать?

Ответы [ 4 ]

3 голосов
/ 01 сентября 2011

Анализ вашего документа с помощью dom, поиск всех тегов "a" и последующая замена могут быть хорошим способом. Кто-то уже прокомментировал, разместив вам эту ссылку , чтобы показать вам, что регулярные выражения не всегда лучший способ работы с HTML.

Ayways этот код должен работать:

<?php
$dom = new DOMDocument;
//html string contains your html
$dom->loadHTML($html);
?><ul><?
foreach( $dom->getElementsByTagName('a') as $node ) {
    //look for href attribute
    if( $node->hasAttribute( 'href' ) ) {
        $href = $node->getAttribute( 'href' );
        // change hrefs value
         $node->setAttribute( "href", preg_replace( "/\/app\/\?query=(.*)/", "/newapp/?q=\1", $href ) );
    }
}
//save new html
$newHTML = $dom->saveHTML(); 
?>

Обратите внимание, что я сделал это с помощью preg_replace, но это можно сделать с помощью str_ireplace или str_replace

$newHref = str_ireplace("/app/?query=", "/newapp/?q=", $href);
3 голосов
/ 01 сентября 2011

Вы должны передать действительный обратный вызов [документы] в качестве второго параметра: имя функции, анонимная функция и т. Д.* Вот пример:

function my_replace_callback($match) {
    $q = str_replace('_', '+', $match[2]);
    return $match[1] . '="http://www.site.com/newapp/?q=' . $q;
}
$content = preg_replace_callback('#(href)="http://www.site.com/app/?query=([^:"]*)(?:")#', 'my_replace_callback', $content);

Или с PHP 5.3:

$content = preg_replace_callback('#(href)="http://www.site.com/app/?query=([^:"]*)(?:")#', function($match) {
    $q = str_replace('_', '+', $match[2]);
    return $match[1] . '="http://www.site.com/newapp/?q=' . $q;
}, $content);

Вы также можете попробовать использовать анализатор HTML вместо регулярного выражения: Как выразбирать и обрабатывать HTML / XML в PHP?

0 голосов
/ 01 сентября 2011

Передача массивов в preg_replace в качестве шаблона и замены:

preg_replace(array('|/app/|', '_'), array('/newappp/', '+'), $content);
0 голосов
/ 01 сентября 2011

Или вы можете просто использовать preg_match () и собирать подходящие строки. Затем примените str_replace () к одному из совпадений и замените «+» на «_».

$content = preg_match('#href="\/[^\/]\/\?query=([^:"]+)#', $matches)
$matches[2] = 'newapp';
$matches[4] = str_replace('_', '+', $matches[4]);
$result = implode('', $matches)
...