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

kanaris

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

Нужно разделить URL'ы следующих видов:

elkg/sadg/ewn/gh_er/ew/dev/core/urltest/2007/02/03/sdrgkjl.html
elkg/sadg/ewn/gh_er/ew/dev/core/urltest/2007/02/03/666

на составляющие:

1) elkg/sadg/ewn/gh_er/ew/dev/core/urltest/ (путь, каждое звено может состоять из больших и маленьких лат. букв, _ и -, звеньев может быть от нуля до +бесконечности)
2) 2007/02/03/ (дата. ее может вообще не быть, может состоять из года; года и месяца; года, месяца и числа)
3) sdrgkjl.html (файл, может быть не указан, имя состоит из a-z, A-Z, 0-9, -, _, а расширение только html)
4) 666 (файл без расширения, якобы номер страницы, представляет собой только число. элемент может не встречаться)

должно работать с урлами любого вида:

elkg/sadg/ewn/gh_er/ew/dev/
core/urltest/
urltest/2007/02/
sdfsdf/sdrgkjl.html
core/urltest/25

и тд.

Пробовал следующее:

PHP:
$url='elkg/sadg/ewn/gh_er/ew/dev/core/urltest/2007/02/03/sdrgkjl.html';

preg_match('|([a-z_\-\.]+[\/])*?(\d{2,4}[\/]){1,3}?([\d]*)([a-z_-]+\.[a-z]{3,4})|i',$url,$out);

echo '<pre>'.print_r($out,true).'</pre>';
echo $url;
выводит вот что:

Код:
Array
(
    [0] => urltest/2007/02/03/sdrgkjl.htm
    [1] => urltest/
    [2] => 03/
    [3] => 
    [4] => sdrgkjl.htm
)
Не правильно в общем! Кто поможет?
 

kanaris

Новичок
Автор оригинала: dimagolov
чем плох explode и анализ полученных элементов?
а всем. ну и получится массив из папок, разделенных слешами, и еще нужно куча кода для поиска даты, номера страницы, имя файла и тд. в этом массиве:)
 

dimagolov

Новичок
Куча кода это сколько? Смещение даты от конца у тебя фиксированное, формат тоже известен, то есть ИМХО одно условие if на соответствие даты шаблону. Ну еще одна строка чтобы определить номер ли последний компонент или не номер, то есть номер страницы или имя файла. Аж 2 строки.
А эфективность выполнения будет на порядок выше чем любой регулярки.
 

kanaris

Новичок
уже разобрался, вотЪ

PHP:
preg_match('|(([a-z_\-\.]+[\/])*)(((\d{2,4}[\/]){1,3})?)([\d]*)([a-z0-9_\-]+[\.][a-z]{3,4})?|i',$url,$out);

echo $out[1].'<br/>'; // путь
echo $out[3].'<br/>'; // дата
echo $out[6].'<br/>'; // номер страницы
echo $out[7].'<br/>'; // имя файла
регулярки форева!
 

Sepuka

Новичок
раз разобрался, подскажи тогда такую вещь:
как удалить спецсимволы html?
например пишу так:
PHP:
 preg_replace('| (& .*? ;) |ix', " ", $text)
тогда удалятся все типа
PHP:
&quot; &nbsp; &laquo;
и т.д. а вот строка --&gt; не удаляется.
а поидее должны только два тире остаться. Ни как не пойму.
 

kanaris

Новичок
Автор оригинала: Sepuka
раз разобрался, подскажи тогда такую вещь:
как удалить спецсимволы html?
например пишу так:
PHP:
 preg_replace('| (& .*? ;) |ix', " ", $text)
тогда удалятся все типа
PHP:
&quot; &nbsp; &laquo;
и т.д. а вот строка --&gt; не удаляется.
а поидее должны только два тире остаться. Ни как не пойму.
preg_replace('|(&[a-z]+;)|Ui','',$text);
 

Sepuka

Новичок
Спасибо, щас попробую так. Но мне интересно почему не подходит тот вариант? Вроде как должен
 

kanaris

Новичок
Автор оригинала: Sepuka
Спасибо, щас попробую так. Но мне интересно почему не подходит тот вариант? Вроде как должен
preg_replace('| (& .*? ;) |ix', " ", $text)

здесь знак вопроса обозначает "ноль или один". А два пробела вокруг круглых скобок тоже учитываются при поиске выражения. Вот оно заменило " &nbsp; ", а "--&lt;" нет. Почитай ман про квантификаторы, модификаторы и символьные классы. http://ua2.php.net/manual/ru/book.pcre.php
 

Sepuka

Новичок
два пробела для удобочитаемости, а если ставишь x то они игнорируются, можно даже в несколько строк записать шаблон, если бы я хотел пробелы то поставил бы \s Поэтому я и не понял почему выражение подходящее по шаблону не подходит к идентичному выражению только с двумя тире в начале. Знак вопроса записаный вместе с .* говорит о том что нужно взять сколько угодно любых символов, но не слишком много, т.е. до точки с запятой.
 
Сверху