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

clevel

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

есть шаблоны для переделки относительных путей на странице на абсолютные:
PHP:
$fc[]="/(src|background|href)=([\"|']?)([^http|ftp|https].*)([\"|']?)/im";
$tc[]="\\1=\\2".$short."\\3\\4";
echo preg_replace($fc,$tc,$data);
в чем трабла: надо, чтобы для тега iframe этих замен не происходило, иначе в слечае iframe src="about:blank" он подменяет это на абсолютный путь+"about:blank" и сервер выдает мне:
Forbidden.You don't have permission to access /domain/about:blank on this server.
Подскажите, на что изменить это правило, чтобы заменяло пути с учетом этого исключения?
П.С.: можно просто, если встречается в src=about:blank не подменять пути
 

Yukko

Новичок
Полностью кусок кода с проверочной строкой (где должно совпать, а где не должно) привел бы, сразу, может быть и рег получил... а так даже при объяснении, что у тебя делается, выдумавать что-то от себя (значения $data, $short) не хочется.

ИМХО, тебе нужно использовать вот такую конструкцию:
(?<!iframe) Негативная ретроспективная проверка, проверяет, не совпадает ли слева, если не совпдает, то совпадение найдено, если совпадает, то общего совпадения рега нет.
 

clevel

Новичок
PHP:
$data="<IFRAME height=250 id=pagetext src=\"about:blank\" width=580></IFRAME>
<img src=data/ifon.gif>
<td background=img/fon.gif>";
Надо, чтоба во фрейме src не изменился, а во всех других, img,td изменился. Так понятно объяснил?
Интересует момент. где идет отрицание списка: [^http|frp|https|about:blank]. Знаю, что не правильно. так как для этих скобок идет отрицание символов, а не строк. Однако с конструкцией (?!foo)bar из мана не допер, как сделать
 

Yukko

Новичок
Тупой вопрос, что есть $short вот тут:
$tc[]="\\1=\\2".$short."\\3\\4";
Второй тупой вопрос, почему он идет перед \\3?

молодец, наше сам в какую сторону копать... я ошибся в певом своем посте, не слева надо чтобы не совпадало, а справа!
Если я правильно все догнал, тогда вот:
$data="<IFRAME height=250 id=pagetext src=\"about :blank\" width=580></IFRAME>
<img src=data/ifon.gif>
<td background=img/fon.gif>";
$short = "bloody_short";
$fc[]="/<(?!iframe).*(src|background|href)=([\"|']?)([^http|ftp|https].*)([\"|']?)>/im";
$tc[]=" \\1=\\2".$short."\\3\\4";
echo htmlspecialchars(preg_replace($fc,$tc,$data));

если нет, то тогда объясняй дальше, где неправильно...
 

Yukko

Новичок
даже вот так будет лучше
$fc[]="/<(?!iframe)[a-z0-9\s'\"]*(src|background|href)=([\"|']?)([^http|ftp|https].*)([\"|']?)>/im";
 

clevel

Новичок
наверное, более правильным будет сделать отрицание здесь:([^http|ftp|https].*), это лучше, чем частная ситуация с фреймами...
$short="http://domain.ru/";
 

Yukko

Новичок
clevel
не понимаю... чем тебе не нравится:
fc[]="/<(?!iframe|img)[a-z0-9\s'\"]*(src|background|href)=([\"|']?)([^http|ftp|https].*)([\"|']?)>/im";
или возьми сделай перменную, заноси в нее тег, который хочешь, чтобы фильтровался и вперед! подставляй вместо iframe, ты никогда не создашь универсального инструмента...

Оффтопик: Извини за критику, мы что реги на заказ пишем или помогаем не сгореть? кажется, второе
Народ, подскажите. плз. Горю...
Реги на заказ, я пишу только для себя! Мне абсолютно не внапряг тебе помочь, ибо написание этого рега три минуты дела, но ты поступаешь как плохой заказчик, сначала выдвинул одни требования к продукту, а потом, когда он заработал, начинаешь мудрить, что вот было бы неплохо... Почитай то, что ты написал сначала, а потом прочитай свой последний пост. :( разочарован.
 

clevel

Новичок
это из первого поста:
П.С.: можно просто, если встречается в src=about :blank не подменять пути
пробую это правило для такого чуть усложненого в целях проверки примера:
PHP:
 $data="<IFRAME height=250 id=pagetext src=\"about:blank\" width=580></IFRAME>".
       "<img width=\"268\" height=\"86\" nowrap src=data/ifon.gif>".
       "<td width=\"268\" height=\"86\" nowrap background=img/fon.gif style=\"z-index:10\">";
выясняется очень интересная тема: если ставить перенос строки в конце каждой подстрочки(где у меня логически разделены фрейм,картинка,ячейка), то для подстрочек, которые начинаются с новой строки, применяется правило. иначе нет. Странно, ведь я указан флаг m - multiline.
А чего добавить, чтобы в этой строчке несколько искомых подстрок найти?

Yukko, не расстраивайся, огромное тебе спасибо, просто на тестовом примере у меня тоже все хорошо получилось, однако когда подставил в реальный пример, результат был прямо противоположный...
Вот и вылезла, надеюсь последняя кракозябла насчет нескольких искомых подстрок в строке.. :(
Самому это не нравится, из-за какой-то мелочи столько времени угрохал...
 

si

Administrator
Странно, ведь я указан флаг m - multiline.
может посмотрите в мануале на что влияет это модификатор ?
m (PCRE_MULTILINE)
By default, PCRE treats the subject string as consisting of a single "line" of characters (even if it actually contains several newlines). The "start of line" metacharacter (^) matches only at the start of the string, while the "end of line" metacharacter ($) matches only at the end of the string, or before a terminating newline (unless D modifier is set). This is the same as Perl.

When this modifier is set, the "start of line" and "end of line" constructs match immediately following or immediately before any newline in the subject string, respectively, as well as at the very start and end. This is equivalent to Perl's /m modifier. If there are no "\n" characters in a subject string, or no occurrences of ^ or $ in a pattern, setting this modifier has no effect.
 

clevel

Новичок
блин, ты меня заводишь... до завтра потерпишь?
постараюсь :)
пока вышел самым тупым способом: после всех превращений делаю обратную конвертацию для случая http://domain/about:blank. Но это через одно место. куда солнце не заглядывает :)
может посмотрите в мануале на что влияет это модификатор ?
да смотрел и этот, и дургие флаги(модификаторы), не нашел решения данного проблемы.. :(
 

Yukko

Новичок
О! с утра голова посветлее :)
У меня вопрос. Ты вот этим ([^http|ftp|https].*) в тупик ставишь... какие http://, ftp:// https:// в относительных путях? В относительных путях у тебя два варианта:
1. directory/file.ext
2. "about :blank"
Тебе надо сделать:
1. http://host.com/directory/file.ext
2. оставить "about :blank
Правильно? Если нет, то где я неправ?
 

clevel

Новичок
нет, могут же быть не только относительные, но и абсолютные пути и ссылки.
Вот поэтому-то и надо только относительные ссылки вида img/fon.gif, /data/img.jpg переделать, а таких видов оставить:
http://,ftp://,https://,mailto://,javascript:,about:src.
Эта конструкция ([^http|ftp|https].*) не правильная, как я уже говорил, но видно в этом желание сделать отрицание для нескольких вариантов начала адреса.
Чтобы была понятна вся картина, объясняю, где это я использую. Есть дизайн страниц, где ссылки до картинок и файлов у меня относительны, и есть контент, которые юзеры заполняются через эмулятор ворда. Как в первом, так и во втором случае есть относительные и абсолютные ссылки и пути. Вот первые-то из них мне изменить и надо.
 

Silent

Новичок
> Эта конструкция ([^http|ftp|https].*) не правильная

Угу, причем абсолютно. В квадратных скобках может быть только символьный класс, который имеет свой собственный синтакс. То, что написано выше, фактически означает: любой символ, кроме "htpfs|", за которым следует любое количество любых символов. Тут скорее нужно применять (?!http|ftp|https).

А не лучше ли просто шаблоном найти все URL, а затем уже парсить их с помощью parse_url($url) и деалть с ними что угодно. Мало ли какой URL может встретиться. Шаблон никогда не будет универсальным.
 

Yukko

Новичок
Вот что у меня получилось... за конструкцию не ругать, что можно было сделать кавычки необязательными, я не догоняю, как вот такая конструкция (\")* работает с опережающей проверкой (?!bla), когда пойму, тогда перепишу. Тестируй! Жду комментариев!

$data = preg_replace("/(src|background|href)=\"(?!http|ftp|https|about..?blank)(.*?)\"/sim","\\1=\"http://fuck.ru/\\2\"",$data);
echo "<br>".nl2br(htmlspecialchars(preg_replace("/(src|background|href)=(?!\"|http|ftp|https|about..?blank)(.*?)/sim","\\1=http://bloody_short.ru/\\2",$data)));
 

Yukko

Новичок
А, забыл сказать, результат будет виден только после того, как текст пройдет оба рега. Реги располагать в том порядке, в котором я написал...
nl2br и htmlspecialchars нужны для отладки...
 

clevel

Новичок
да, твоя конструкция для 90% случаев срабатывает:

$fc[]="/(src|background|href)=\"(?!http|ftp|https|about:blank|javascript:)(.*?)\"/sim";
$fc[]="/(src|background|href)=(?!\"|http|ftp|https|about:blank|javascript:)(.*?)/sim";
$tc[]="\\1=\"".$short."\\2\"";
$tc[]="\\1=".$short."/\\2";

трабла в правильных кавычках... пытаюсь сделать так ([\"|']?), не хочет понимать :(
 

clevel

Новичок
да, повал идет на такой конструкции:
onmouseover=\"this.src='$short/img/search.gif'\"
по идее, так как у нас уже есть http в начале ссылки. то не дожен он ее трогать, ан нет.. все трабла в кавычках...
 
Сверху