регулярное выражение

Hall9000

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

Доброго времени суток!
недавно начал изучать рег. выражения
есть текст веб-страницы:

PHP:
$text='<!--[if gte vml 1]><v:shapetype id="_x0000_t75"    coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe"    filled="f" stroked="f">    <v:stroke joinstyle="miter"/>    <v:formulas>     <v:f eqn="if lineDrawn pixelLineWidth 0"/>     <v:f eqn="sum @0 1 0"/>     <v:f eqn="sum 0 0 @1"/>     <v:f eqn="prod @2 1 2"/>     <v:f eqn="prod @3 21600 pixelWidth"/>     <v:f eqn="prod @3 21600 pixelHeight"/>     <v:f eqn="sum @0 0 1"/>     <v:f eqn="prod @6 1 2"/>     <v:f eqn="prod @7 21600 pixelWidth"/>     <v:f eqn="sum @8 21600 0"/>     <v:f eqn="prod @7 21600 pixelHeight"/>     <v:f eqn="sum @10 21600 0"/>    </v:formulas>    <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>    <o:lock v:ext="edit" aspectratio="t"/></v:shape><![endif]--> <!--[if gte vml 1]><v:shapetype id="_x0000_t75"    coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe"    filled="f" stroked="f">    <v:stroke joinstyle="miter"/>    <v:formulas>     <v:f eqn="if lineDrawn pixelLineWidth 0"/>     <v:f eqn="sum @0 1 0"/>     <v:f eqn="sum 0 0 @1"/>     <v:f eqn="prod @2 1 2"/>     <v:f eqn="prod @3 21600 pixelWidth"/>     <v:f eqn="prod @3 21600 pixelHeight"/>     <v:f eqn="sum @0 0 1"/>     <v:f eqn="prod @6 1 2"/>     <v:f eqn="prod @7 21600 pixelWidth"/>     <v:f eqn="sum @8 21600 0"/>     <v:f eqn="prod @7 21600 pixelHeight"/>     <v:f eqn="sum @10 21600 0"/>    </v:formulas>    <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>    <o:lock v:ext="edit" aspectratio="t"/></v:shape><![endif]--> <!--[if gte vml 1]><v:shapetype id="_x0000_t75"    coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe"    filled="f" stroked="f">    <v:stroke joinstyle="miter"/>    <v:formulas>     <v:f eqn="if lineDrawn pixelLineWidth 0"/>     <v:f eqn="sum @0 1 0"/>     <v:f eqn="sum 0 0 @1"/>     <v:f eqn="prod @2 1 2"/>     <v:f eqn="prod @3 21600 pixelWidth"/>     <v:f eqn="prod @3 21600 pixelHeight"/>     <v:f eqn="sum @0 0 1"/>     <v:f eqn="prod @6 1 2"/>     <v:f eqn="prod @7 21600 pixelWidth"/>     <v:f eqn="sum @8 21600 0"/>     <v:f eqn="prod @7 21600 pixelHeight"/>     <v:f eqn="sum @10 21600 0"/>    </v:formulas>    <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>    <o:lock v:ext="edit" aspectratio="t"/></v:shape><![endif]-->';
PHP:
preg_replace('/(?s)<\!--\[if gte vml 1]>.*?<\!\[endif]-->/','',$text);
нужно произвести замену текста, стоящий внутри тэгов <!--[if gte vml 1]> и <![endif]-->
по рег. выражению
/(?s)<\!--\[if gte vml 1]>.*?<\!\[endif]-->/
найдено:Всего совпадений 3

как только выполняется замена:
preg_replace('/(?s)<\!--\[if gte vml 1]>.*?<\!\[endif]-->/','',$text);

переменная $text пустая

и вот так
PHP:
preg_match('/(?s)<!--\[if gte vml 1\]>.*?<!\[endif\]-->/',$text,$matches);
var_dump($matches);
array
empty

что не правильно?
 

tz-lom

Продвинутый новичок
отлаживать регулярки в внешней программе это правильно
а вот забывать что в PHP \ надо экранировать это неправильно
 

Hall9000

Новичок
Автор оригинала: tz-lom
отлаживать регулярки в внешней программе это правильно
а вот забывать что в PHP \ надо экранировать это неправильно
последнее выражение было верно, но не пойму где собака зарыта
 

john.brown

просто кулибин
Hall9000
Во первых, не совсем понятно, что ты имел ввиду вот этим - (?s).
Во вторых, если надо заменить то, что "внутри тэгов <!--[if gte vml 1]> и <![endif]-->", то в регулярке наверно надо скобками выделить фрагмент, который внутри, потом уже найти их все при помощи preg_match_all(), а потом уже при помощи str_replace() заменить найденные совпадения.
 

Hall9000

Новичок
Автор оригинала: john.brown
Hall9000
Во первых, не совсем понятно, что ты имел ввиду вот этим - (?s).
Во вторых, если надо заменить то, что "внутри тэгов <!--[if gte vml 1]> и <![endif]-->", то в регулярке наверно надо скобками выделить фрагмент, который внутри, потом уже найти их все при помощи preg_match_all(), а потом уже при помощи str_replace() заменить найденные совпадения.
так мне и тэги <!--[if gte vml 1]> и <![endif]--> надо удалить
PHP:
preg_match_all('/(?s)<\!--\[if gte vml 1\]>.*?<\!\[endif\]-->/',$text,$matches)
найдено, ну и я думаю путем замены текста на:
PHP:
preg_replace('/(?s)<\!--\[if gte vml 1\]>.*?<\!\[endif\]-->/','',$text);
-~{}~ 23.08.10 09:43:

ладно фигня....
вот думаю над простым.. совершенно очевидно
PHP:
$filename="file.htm";
$pattern1="/<!--\[if !mso\]>.*<!\[endif\]-->/s";
$content=file_get_contents($filename);
//content принимает такое содержимое
$content="<link rel=File-List href=filelist.xml>
<link rel=Edit-Time-Data href=editdata.mso>
<!--[if !mso]>
<style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
x\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<![endif]-->
<link rel=Stylesheet href=stylesheet.css>
<style>
<!--table
	{mso-displayed-decimal-separator:"\,";
	mso-displayed-thousand-separator:" ";}
@page
	{margin:.75in .7in .75in .7in;
	mso-header-margin:.3in;
	mso-footer-margin:.3in;}
-->
</style>
<![if !supportTabStrip]>";
preg_replace($pattern1,'',$content,-1,$count);
//при чем $count=1 т.е. типа найдено одно значение
file_put_contents($filename, $content);
после чего файл нифига не измененный
непойму в чем дело
 

Hall9000

Новичок
ну да, типа должна удалится часть некоторая, которая описана в шаблоне, но файл остался без изменений, все что внутри тэгов не удалилось(заменилось)
хмм, хотите сказать что надо писать так:
PHP:
$content=preg_replace($pattern1,'',$content,-1,$count);
file_put_contents($filename, $content);
ну конечно же :) затупил после preg_match_all
 

Hall9000

Новичок
Автор оригинала: john.brown
Да, именно так.
тогда технический вопрос
выполняется код:
PHP:
$content=preg_replace($pattern1,'',$content,-1,$count);
после чего к примеру $count=216, а $content при этом пустая строка.
как же быть?

в файле есть картинка, какого хрена Майкрософт запихивает картинку в файл htm внутри тегов <v:shape></v:shape> и её же (картинку) сохраняет отдельным файлом png.
Вот чтобы избавится от мусора необходимо избавиться от него, дабы не занимать память.
Покажите пожалуйста свой вариант, как избавиться от тегов и все что внутри них:
PHP:
$pattern1="/<v:shape.*>.*<\/v:shape>/sU";
$pattern2="/<!--\[if gte vml 1\]>.*<!\[endif\]-->/sU";
что-то неполучается :(

P.S.
пример:
1. создать файл xls внутрь поместить любую картинку
2. сохранить это все в веб-страницу
3. ну и смотреть файл htm в папке с названием файла


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

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

john.brown

просто кулибин
Разобратся, что и как у тебя заменяется и что из себя представляет исходная строка, если пустая строка не является ожидаемым результатом :)

Вот в самом первом твоем примере как раз пустая строка и остается, ибо ничего, окромя удаляемого, там нет :) подозреваю, что и в других строках может быть так же...
 

Hall9000

Новичок
Автор оригинала: john.brown
Вот в самом первом твоем примере как раз пустая строка и остается, ибо ничего, окромя удаляемого, там нет :) подозреваю, что и в других строках может быть так же...
я часть контента вырезал, дабы не загружать форум непонятной писаниной сохраненной Майкрософтом
 

john.brown

просто кулибин
Подозреваю, что беда в жадности квантификаторов. Вот такая вот конструкция:
Код:
<v:shape.*>
у тебя съедает все, что попадает между <v:shape и самой последней закрывающей >. Чтоб так небыло, пользуй ограничение жадности - <v:shape.*?> - так туда попадет все только до первой >
 

Hall9000

Новичок
Автор оригинала: john.brown
Подозреваю, что беда в жадности квантификаторов. Вот такая вот конструкция:
Код:
<v:shape.*>
у тебя съедает все, что попадает между <v:shape и самой последней закрывающей >. Чтоб так небыло, пользуй ограничение жадности - <v:shape.*?> - так туда попадет все только до первой >
правильно, потому что тег <v:shape > включает в себя типа: <v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">
эмм... у меня ограничение жадности стоит в конце выражения /sU
 

john.brown

просто кулибин
А, сорри, не пользую я модификатор U. Тогда, в моем понимании, и проверяя, оно (/<v:shape.*>.*<\/v:shape>/sU) делает все, как положено. применяя его к строке из первого поста, остается
Код:
<!--[if gte vml 1]><![endif]--> <!--[if gte vml 1]><![endif]--> <!--[if gte vml 1]><![endif]-->
что и ожидалось.
 

Hall9000

Новичок
еще раз повторюсь, может не видели:
P.S.
пример:
1. создать файл xls внутрь поместить любую картинку
2. сохранить это все в веб-страницу
3. ну и смотреть файл htm в папке с названием файла


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

john.brown

просто кулибин
Ну не буду же я вместо вас создавть файлы, и изучать, что же там М$ наворатил с картинками :) Это уж, плз, самостоятельно.

Рег работает. Смотрите, что в файле меняется после отчистки и добавления еще картинок.

П.С. использовать продукты M$ (полагаю Ворд) для создания html, по меньшей мере странно ;)
 

Hall9000

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

очень жаль... дело в том что на маленьких файлах это все выполняется, а вот если файл становится чуть больше, к примеру в 2Мб то тут палка в колеса...
 

john.brown

просто кулибин
Если на маленьких все происходит, то траблы, имхо, не регом, а с перерасходом памяти или чем то подобном.
 

Hall9000

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

john.brown

просто кулибин
Ограничения по памяти имеется в php.ini - memory_limit. Но постарайтесь все же для начала выяснить более точно, в чем проблема - error_reporting включите, логи поизучайте...
 
Сверху