Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Не пойму почему не работает регулярное выражение


Автор: V0fka 11.3.2016, 17:20
Есть такая строка

test1
<script>
var x = "sfsdf";
</script>
test2

Хочу убрать из неё тег script и то, что внутри него. Пробую это сделать так:

Код

$output = preg_replace("/<script>[\n.]*<\/script>/", "", $input);


Но в результате ничего не происходит. Подскажите, пожалуйста, почему?

Автор: ksnk 11.3.2016, 17:54
Код

/<script>.*?<\/script>/s

`?` поможет избежать странных ситуаций с множеством скриптов.
модификатор `s` позволит точке захватывать и символы перевода строки.

Почему не сработал символьный класс - мутная история, даже добавление \r не помогает. 

Автор: V0fka 11.3.2016, 18:22
ksnk, так работает, спасибо!

Цитата(ksnk @  11.3.2016,  17:54 Найти цитируемый пост)
`?` поможет избежать странных ситуаций с множеством скриптов.

А можно немножко подробнее? Я не могу понять зачем тут "?". Попробовал без него, тоже работает вроде. smile 

Автор: ksnk 11.3.2016, 18:27
Код

test1
<script>
var x = "sfsdf";
</script>
test2

test3
<script>
var y = "sfsdf";
</script>
test4


А на таких данных без вопросика сработает?

Автор: _zorn_ 12.3.2016, 06:21
В пхп кто то еще использует слэши для определения границ регекспов ?

Неужели так веселей с заборами
Код

'/http:\/\/([^\/]+?)\//'

чем так ?
Код

'#http://([^/]+?)/#'

Где быстрее поймёшь что делает регулярка, в первом или втором примере ?   smile 

Цитата(ksnk @  12.3.2016,  00:54 Найти цитируемый пост)
`?` поможет избежать странных ситуаций с множеством скриптов.

Ситуации не странные. По умолчанию + и * жадные (берут все до последнего вхождения). Вопросик инвертирует жадность (берут до первого вхождения если были жадные). 
Есть даже модификатор чтобы квантификаторы были не жадные.

Цитата(ksnk @  12.3.2016,  00:54 Найти цитируемый пост)
Почему не сработал символьный класс - мутная история, даже добавление \r не помогает.  

Ничего мутного. Там впридачу еще двойные кавычки. Так что \n пхп УЖЕ перевёл в перевод строки перед тем как отправить на растерзание движку регекспов (с двойными кавычками надо было \\n - сами себе заборы городите).
Чтобы избегать таких "странных" ситуаций, я всегда использую одинарные кавычки и решетки как границу регекспа.

В вашем же случае правильная регекспа будет выглядеть так (иначе можно будет замутить <script>alert('OLOLO')</script   > и браузер это отработает)
Код

$output = preg_replace('#<script.*?>.*?</script.*?>#s', '', $input);

Модификатор "s" включает переводы строки в "."

ЗЫ. А почему не htmlspecialchars ?

Автор: ksnk 12.3.2016, 11:30
Цитата(_zorn_ @  12.3.2016,  06:21 Найти цитируемый пост)
Ничего мутного. 

Да ну? Тот факт, что точка НЕ может использоваться как элемент символьного класса не мутен?  
По идее, класс [\r\n.] должен бы выбирать все символы, включая перевод строк, а на деле такое может только конструкция ([\r\n]|.) 
Ничего мутного?  smile  

Автор: _zorn_ 12.3.2016, 13:08
Цитата(ksnk @  12.3.2016,  18:30 Найти цитируемый пост)
Да ну? Тот факт, что точка НЕ может использоваться как элемент символьного класса не мутен?  

С чего бы это ? В симольном класе точка - и есть точка, а не любой символ. Хз что вы там себе наприбумывали....
Цитата(ksnk @  12.3.2016,  18:30 Найти цитируемый пост)
По идее, класс [\r\n.] д

Да нидолжно быть никаких "по идее" если хочешь разобраться.

В данном случае сделай
echo '\nOLOLO';
echo "\nOLOLO";
И попробуй разобраться

Цитата(ksnk @  12.3.2016,  18:30 Найти цитируемый пост)
Ничего мутного?  smile   

Прочитай про модификаторы... хотя бы жадности.

Автор: V0fka 14.3.2016, 10:39
Цитата(ksnk @  11.3.2016,  18:27 Найти цитируемый пост)
А на таких данных без вопросика сработает? 

Не работает. Не понимаю пока почему, буду разбираться smile 

_zorn_, по тому, что вы написали тоже пока ничего не понял. Помедитирую на досуге. smile
Пока отвечу на
Цитата(_zorn_ @  12.3.2016,  06:21 Найти цитируемый пост)
ЗЫ. А почему не htmlspecialchars ?

Есть wysiwyg редактор, который на выходе возвращает html. Этот html записывается в базу, а потом я его оттуда просто отображаю на страничке. Если сделать htmlspecialchars (я пробовал), тогда html отображается в виде текста. А тема эта появилась, потому что http://forum.vingrad.ru/forum/act-ST/f-490/t-386909/unread-1.html, что какая-то сволота каким-то образом вставила javascript в базу. Это при том, что я как не пробовал, wysiwyg у меня скрипт зарезает. Поэтому я решил попробовать вырезать js код.

Допускаю, что так, как я сейчас пытаюсь решить эту проблему, из приличных людей никто так не делает. Если это так, то может быть подскажете, как делают?

Автор: ksnk 14.3.2016, 14:16
Цитата(V0fka @  14.3.2016,  10:39 Найти цитируемый пост)
Не работает. Не понимаю пока почему, буду разбираться  

Нужно почитать про `?`и "жадность". Своими словами - конструкция .* или .+ работает в 2 режимах - жадный и нежадный. В первом захватывается последняя подходящая конструкция, в последнем - первая. По умолчанию, конструкция с точкой - в жадном режиме, вопросик переключает эти режимы.

Автор: V0fka 15.3.2016, 12:47
ksnk, почитаю, спасибо! А подскажите, если можете, насчет
Цитата(V0fka @  14.3.2016,  10:39 Найти цитируемый пост)
Допускаю, что так, как я сейчас пытаюсь решить эту проблему, из приличных людей никто так не делает. Если это так, то может быть подскажете, как делают? 


Автор: ksnk 15.3.2016, 12:57
Сначала нужно описать саму проблему. Что за тексты, откуда они берутся,  кем написаны (скрипт, чужие люди, собственные админы) Зачем оттуда нужно выкидывать какие-то элементы? Только ли скрипты оттуда нужно выкидывать? Может еще и ифреймы и активные элементы?
После этого можно будет формулировать подходы к решению.

Автор: V0fka 15.3.2016, 13:20
ksnk, не не. Возможно вы подскажете как не допустить такого, в принципе. Выкидывать <script> это как костыль. Как я выше писал, есть wysiwyg редактор, из которого можно получить html разметку. Я её получаю и в том виде, как она есть, без htmlspecialchars и прочего пишу этот html в базу. Потом на определенной странице беру то, что я положил в базу ранее и просто, опять таки без какой-либо обработки, вывожу на страницу и получаю красиво размеченные сообщения. Вопрос в том, что так нормальные люди делают?

Автор: ksnk 15.3.2016, 14:09
Обычно, считается, что в базу попадает уже валидный и корректный код. Просто чтобы не делать обработку каждый раз при выводе. Таким образом проверку и обработку неплохо бы делать перед складированием в базу, сразу после визивига.

Самому писать всю эту чистку довольно заморочно. Есть готовые инструменты, которые все чистят, например http://htmlpurifier.org/ Но он страшно велик. С другой стороны еще и могуч...

Наткнулся на  MarkHtml -  https://habrahabr.ru/post/116607/ 
На первый взгляд - забавно и компактно, хотя сам и не пробовал.  

Автор: V0fka 17.3.2016, 10:18
ksnk, попробую значит прикрутить MarkHtml и дополнительно буду медитировать над "жадностью" и "?".  Спасибо большое за помощь! smile 

_zorn_, вам так же спасибо за ответы!

Автор: V0fka 18.3.2016, 13:46
ksnk, почитал про жадность, появилась пара вопросов smile . Я правильно понимаю, что /<script>.*?<\/script>/s можно записать как /<script>.*<\/script>/sU ?
Ещё читал, как вставлять модификаторы в шаблон, пишут, что вместо ? можно ещё указывать (?U). С ? удобнее, спору нет, но интереса ради я попробовал и с (?U): /<script>.*(?U)<\/script>/s. Но оно так не работает. Почему?

_zorn_, раскурил вашу регулярку. Вроде понял. Спасибо! И решетками обрамлять выражение, на первый взгляд, действительно удобнее.

Автор: _zorn_ 18.3.2016, 15:03
Цитата(V0fka @  18.3.2016,  20:46 Найти цитируемый пост)
Но оно так не работает. Почему?

Потому что вы не правильно поняли прочитанное. А вообще такие вещи лучше не использовать. Потому что движков регекспов не один.
Подобные вещи (?U) меняют модификаторы для всего что ПОСЛЕ них. Вот же пример с пхп.нет
Цитата
Если изменение опции происходит на самом верхнем уровне (т.е. вне подмаски), изменение будет применено к оставшейся части шаблона. Таким образом, /ab(?i)c/ совпадет только с "abc" и "abC".

напоминаю что "i" - регистронезависимость.

Вобщем не путайте других и сами себя и используйте вопросик smile
К тому же 
Цитата

U (PCRE_UNGREEDY)
....
Такая возможность не совместима с Perl.

А если что то не совместимо с чем то (напомню что в PCRE первая буква значит Perl, а ПХП юзает PCRE... Вот такая вот петрушка), то стоит избегать использования.

Автор: V0fka 24.3.2016, 18:45
_zorn_, спасибо за ответ!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)