Помогите составить регулярное выражение

Leech5

Новичок
Помогите составить регулярное выражение

Пытаюсь написать скрипт для подсчёта количества ссылок на страничке.
Вот что я написал:
PHP:
function get_links($url) {
   if( !($body = @file_get_contents($url)) ) return FALSE;
   preg_match_all("|href=(.*)>|U", $body, $data);
   return $data;
}
чувствую что можно было бы сделать и получше... сложновато пока разобраться с этими закарючками. :)
вроде работает, но хотелось бы чтоб он не учитывал mailto, https и ссылки не повторялись. Как это сделать?

В дальнейшем хотелось бы чтоб скрипт различал внешние и внутренние ссылки. Пока не придумал еще как. Подскажите пожалуйста
Заранее благодарен!
 

WP

^_^
PHP:
 function x_array_merge($arr1,$arr2)
 {
  if (!is_array($arr1)) {$arr1 = array();}
  if (!is_array($arr2)) {$arr2 = array();}
  $arr = array();
  $s = sizeof($arr1);
  for ($i = 0;$i < $s; $i++) {$arr[$i] = ($arr1[$i] == '')?$arr2[$i]:$arr1[$i];}
  return $arr;
 }
 function get_links($body)
 {
  $pattern  = "/((@import\s+[\"'`]([\w:?=@&\/#\.,_;-]+)[\"'`];)|".
              "(:\s*url\s*\([\s\"'`]*([\w:?=@&\/#\.,_;-]+)".
              "([\s\"'`]*\))|<[^>]*\s+(src|href|url)\=[\s\"'`]*".
              "([\w:?=@&\/#\.,_;-]+)[\s\"'`]*[^>]*>))/i";
  preg_match_all($pattern,$body,$matches);
  return is_array($matches)?$this->x_array_merge($matches[3],$this->x_array_merge($matches[5],$matches[8])):array();
 }
 

Leech5

Новичок
Я видел эти функции с php.net, они не подходят. Выдают очень много лишних ссылок. Основаная проблема в том чтобы исключить в сточке href - mailto, https и т.д. и отличить внешние ссылки от внутренних.
 

WP

^_^
PHP:
<?php
header('Content-type: text/plain');
function get_links($body)
{
 $links = array();
 preg_match_all('~<a .*?href=(([\'"])(.*?)\2|[^\s>]+).*?>~i',$body,$m,PREG_SET_ORDER);
 foreach ($m as $u)
 {
  $link = isset($u[3])?$u[3]:$u[1];
  if (!preg_match('~^https://|mailto:~i',$link)) {$links[] = $link;}
 }
 var_dump($links);
 return $links;
}
$s = '
<a href=test  1	23>
<a href=\'test\' 1	23>
';
get_links($s);
 

Leech5

Новичок
WP
спасибо большое! то что нужно!
я тут пока ожидал ответа попытался написать что-то свое, вот что из этого вышло:
PHP:
$s = '
<a href=test  1    23>
<a href=\'test\' 1    23>
<a  href=mailto:[email protected]>
';
preg_match_all("/(?:href=)(?<!mailto)([^>]*)(?=>)/", $s, $data);
при выводе выдаёт:

Array
(
[0] => Array
(
[0] => href=test 1 23
[1] => href='test' 1 23
[2] => href=mailto:[email protected]
)

[1] => Array
(
[0] => test 1 23
[1] => 'test' 1 23
[2] => mailto:[email protected]
)

)

Вопрос в такой: почему (?<!mailto) не даёт никакого результата? в чем моя ошибка?
 

WP

^_^
А зачем ты сделал запаздывающую проверку? '<' убери.
 

Leech5

Новичок
У меня появилась еще одна проблема с регурярными выражениями.
Я сделал проверку на внутренние ссылки
PHP:
preg_match('~http:\/\/(www\.)?'.$[host.'\/.*?|^\/?(?!http:\/\/).*$~i',$url)
такую ссылку я считаю внутренней, остальные - внешними. В таком состоянии скрипт работает как нужно, но когда я добавил
PHP:
preg_match('~http:\/\/(www\.)?'.$[host.'\/.*?|^\/?(?!http:\/\/).*$|^\/?(?!https:\/\/).*$~i',$url)
скрипт считает что все внутренние. Я так думаю, что со знаками ^ и $ не правильно поступил...
Как нужно?
 

WP

^_^
А нафига такие сложности? [m]parse_url[/m] + [m]isset[/m].
PHP:
$string = 'http://test';
preg_match('~^(?![a-z]+://).*~i',$string,$matches);
var_dump($matches);
 
Сверху