Регулярные выражения (выдернуть из искомой строки подстроку)

timson

Новичок
Регулярные выражения (выдернуть из искомой строки подстроку)

Здрасте!
Осваиваю Рег.Выр.. но вот столкнулся с проблемой (я по С спец.. )

есть в хтмл сылка на картинку
PHP:
<img src="http://php.ru/images/logo.jpg">
вот из нее нужно выделить саму ссылку http://php.ru/images/logo.jpg, и измениьт ее.. и все за один проход.

алгоритм с помощью preg_replace:
- находим сылку match[0] = http://php.ru/images/logo.jpg (1)
- в найденном находим имя файла (после последнего слеша)match[1] = logo.jpg (2)
- заменяем match[0] на $text.match[1] (3)


вот написал шаблон для выдергивания (1) строки
PHP:
$pattern    = = "/img\ssrc=\"(.*?)\">/si";
для (2) отдельно написал
PHP:
$pattern    = "/(?<=\/)[^\/]*(?=\")/si";
а вот как их совместить?? чет не доходит..
 

timson

Новичок
есть любой html файл
PHP:
<html>
...
<img src="http://php.ru/help/images/logo.jpg">
...
</html>
получить нужно

PHP:
<html>
...
<img src="/files/logo.jpg">
...
</html>
 

Gas

может по одной?
PHP:
$text = preg_replace('~src\s*=\s*[\'"].*/images/logo.jpg[\'"]~', 'src="/files/logo.jpg"', $text);
 

timson

Новичок
еслиб так было все просто.. наверно не сколько не понятно написал.

есть же программы, скачивающие сайты из нета, так они парсят хтмл, и изменяют в нем ссылки. вот что-то вроде этого хотел сделать.. пока на примере картинок работаю.. оттачиваю механизм.

PHP:
<html> 
... 
<img src="http://php.ru/help/images/logo.jpg"> 
<img src="http://php.ru/main.png"> 
<img src="menu/page1.gif"> 
... 
</html>
нужно получить

PHP:
<html> 
... 
<img src="files/logo.jpg"> 
<img src="files/main.png"> 
<img src="files/page1.gif"> 
... 
</html>
 

Gas

может по одной?
PHP:
$text = preg_replace('~src\s*=\s*[\'"].*/([^/]+\.[^.]+)[\'"]~U', 'src="files/$1"', $text);
 

white phoenix

Новичок
PHP:
function get_links(&$body)
{
 $pattern  = "/((@import\s+[\"'`]([\w:?=@&\/#._;-]+)[\"'`];)|";
 $pattern .= "(:\s*url\s*\([\s\"'`]*([\w:?=@&\/#._;-]+)";
 $pattern .= "([\s\"'`]*\))|<[^>]*\s+(src|href|url)\=[\s\"'`]*";
 $pattern .= "([\w:?=@&\/#._;-]+)[\s\"'`]*[^>]*>))/i";
 preg_match_all($pattern,$body,$matches);
 return (is_array($matches))?$matches:FALSE;
}
/* $matches[3] содержит ссылки Javascript, $matches[5] ссылки CSS, и $matches[8] содержит обычные URL/SRC/HREF HTML ссылки. Чтобы получить их все в один массив используйте x_array_merge() */
function x_array_merge($arr1,$arr2)
{
 for($i=0;$i<count($arr1);$i++) {$arr[$i]= ($arr1[$i] == '')?$arr2[$i]:$arr1[$i];}
 return $arr;
}
$body = @file_get_contents($url);
$heap = get_links($body);
$links = x_array_merge($heap[3],x_array_merge($heap[5],$heap[8]));
var_dump($links);
Поизучай $heap, скорее всего решит эту задачу.
 

timson

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

щас попробую preg_replace_callback поюзать..
 

timson

Новичок
а разве два прохода эффективно?? по скорости?

а вот с CallBack, я выдергиваю все сылки, и меняю то что нужно. пака вроде работает.. но чет еще нужно довести до ума.

или в два прохода будет эффективнее??


и еще вопрос, есть ли в ПХП потоки?? и средства синхронизации??
 

white phoenix

Новичок
timson
> а разве два прохода эффективно?? по скорости?
Когда как. Запости свой вариант.
> и еще вопрос, есть ли в ПХП потоки?? и средства синхронизации??
[m]pcntl[/m]
 

alan4ick

Guest
Автор оригинала: timson
еслиб так было все просто.. наверно не сколько не понятно написал.

есть же программы, скачивающие сайты из нета, так они парсят хтмл, и изменяют в нем ссылки. вот что-то вроде этого хотел сделать.. пока на примере картинок работаю.. оттачиваю механизм.
IMHO в 2 прохода эта наиболее верный путь, так как первым проходом дергаешь все ссылки, потом загружаешь по полученным ссылкам картинки,смотришь что загрузилось, а что нет, а потом делаешь replace на необходимое.
 

timson

Новичок
да, чет подумал щас. Если средний размер страницы 50-100 кб, и ссылок там на картинки/стили/скрипты 30-100, то можно и в два прохода, т.к. все равно врема на залифку их на фтп на порядок будет выше чем собственно парсинг..

вначале думал вот так сделать:
PHP:
function ReplaceLink ($matches)
{
//	$matches[1] - link to file
//  поставить в очередь для копирования, задание выполняет отдельный поток)
	
	$ptr    = "/(?<=\/)[^\/]*$/si";

	if ( preg_match ( $ptr, $matches[1], $file ) == 0 )
		echo "Not found<br>";
		
	return "img src=\"/dir/".$file[0]."\"";
}

$ptr    = "/(?<=<).*?src\s*=\s*[\'\"](.*?)\"/i";

$new	= preg_replace_callback ($ptr, "ReplaceLink", $prs_src);
прошу сильно не пинать, я в веб-программинге не шарю, делаю как делал бы в прикладном программинге. да и при анализа исходных данных (выще) все равно не эффективно, если бы парсинг на нескольких Мб был, то уже можно было и подумать.

Значит тогда буду в два прохода делать.

-~{}~ 25.12.05 21:10:

(Новое!)

ой.. чет у же почти час сижу, и никак не могу написать выражения чтоб выдернуть из "http://microsoft.ru/images/hello.php?url=param&sgsdg" - "http://microsoft.ru/images/" and "hello" (без кавычек)

PHP:
$url    = "http://www.microsoft.ru/images/hello.php";
$url    = "http://microsoft.ru/images/hello.php?url=param&sgsdg";

$ptr_src    = "/(http:\/\/)?([^\/]+\.[^.]+)([^\?]*)$/U";

if ( preg_match ( $ptr_src, $url, $matches ) == 0 )
	echo "Not found<br>";

for ($i = 0; $i < count($matches); $i++)
{
    echo "$i: ". $matches[$i] . "<br>";
}
выдергивается вот что:
PHP:
0: http://microsoft.ru/images/hello.php?url=param&sgsdg
1: http://microsoft.ru/images/hell
2: o.php?
3: url=param&sgsdg
 

white phoenix

Новичок
timson
Это же элементарно.
PHP:
$url = "http://microsoft.ru/images/hello.php?url=param&sgsdg"; 
$pattern   = '~((?:http://)?(?:[^/]*/)*)([^\.]*)(?:.*)$~';
if (preg_match($pattern,$url,$matches) == 0) { echo "Not found<br>";}
else {var_dump($matches);}
/*
array(3) {
  [0]=>
  string(52) "http://microsoft.ru/images/hello.php?url=param&sgsdg"
  [1]=>
  string(27) "http://microsoft.ru/images/"
  [2]=>
  string(5) "hello"
}
*/
 

sakon

П..и.н..ок
timson
Может тебе стоит посмотреть в сторону [m]parse_url[/m]?
 

zarus

Хитрожопый макак
Обсуждение проблем личинга контента запрещено правилами форума...
 
Сверху