Решено: Прошу помощи с регекспом (php)

Модератор: Модераторы разделов

Аватара пользователя
Ленивая Бестолочь
Бывший модератор
Сообщения: 2760
ОС: Debian; gentoo

Решено: Прошу помощи с регекспом

Сообщение Ленивая Бестолочь »

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

Код: Выделить всё

`%%(.+?)%%`is

(это кусок кода кусабы, если кому интересно).

он, что характерно, предназначен для вычленения

Код: Выделить всё

%%вот таких%%
%%
или вот таких
%%

мест.

я хочу его модифицировать так, чтобы он _не_ срабатывал для текстов с тегом '<br />'. то есть для вот такого, например:

Код: Выделить всё

%%ляляля <br /> ляляля%%

но продолжал в остальном срабатывать как всегда.

он дальше отправляется в функцию preg_replace();
Солнце садилось в море, а люди с неоконченным высшим образованием выбегали оттуда, думая, что море закипит.
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18676
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Решено: Прошу помощи с регекспом

Сообщение Bizdelnick »

Одним регекспом тут вряд ли обойдёшься, добавь вторую проверку.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
Ленивая Бестолочь
Бывший модератор
Сообщения: 2760
ОС: Debian; gentoo

Re: Решено: Прошу помощи с регекспом

Сообщение Ленивая Бестолочь »

Bizdelnick, это плохо, потому, что там в целом класс сделан примерно так:

Код: Выделить всё

        function BBCode($string){
                $patterns = array(
                        '`\*\*(.+?)\*\*`is',
                        '`\*(.+?)\*`is',
                        '`%%((?!<br \\>).+?)%%`is',
<тут ещё много таких>
                $replaces =  array(
                        '<b>\\1</b>',
                        '<i>\\1</i>',
                        '<span class="spoiler">\\1</span>',
<тут ещё много таких>
                $string = preg_replace($patterns, $replaces , $string);

то бишь легко и красиво вставить ещё проверку не получится.
ну то есть я конечно наверно как-нибудь извернуться могу, но я очень надеялся поменять регексп :3

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

Код: Выделить всё

%% xxxx<br \>
%%yyyy%%<br \>
%%

второй уровень вложенности определяется по тому, что коды на одной строке.
таким образом я хотел сделать паттерн для %%xxx%% без тегов <br \> и оставить ещё старый.
чтобы сначала отрабатывал новый, и получалось

Код: Выделить всё

%% xxxx<br \>
<span>yyyy<span><br \>
%%

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

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18676
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Решено: Прошу помощи с регекспом

Сообщение Bizdelnick »

Не проверял, скорее всего не сработает, но может подтолкнёт к размышлениям:
`%%(?!(?!.*%%)<br />).+?)%%`is
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8255
Статус: Маньяк
ОС: Arch, CentOS, Ubuntu

Re: Решено: Прошу помощи с регекспом

Сообщение serzh-z »

Ленивая Бестолоч...

Код: Выделить всё

%%((?!.*?\<br\s\/\>).*)%%


P.S.: рекомендую http://www.phpliveregex.com/
Спасибо сказали:

Аватара пользователя
Ленивая Бестолочь
Бывший модератор
Сообщения: 2760
ОС: Debian; gentoo

Re: Решено: Прошу помощи с регекспом

Сообщение Ленивая Бестолочь »

serzh-z, вот, попробовал твой вариант:

Код: Выделить всё

debdt:/tmp# cat test.php
<?php

$string = '%%test<br \>%%';

printf ( preg_replace('`%%((?!.*?\<br\s\/\>.*?).*)%%`', 'replaced', $string) . "\n");

?>
debdt:/tmp# php test.php
replaced
debdt:/tmp# vi test.php
debdt:/tmp# cat test.php
<?php

$string = '%%test<xx \>%%';

printf ( preg_replace('`%%((?!.*?\<br\s\/\>.*?).*)%%`', 'replaced', $string) . "\n");

?>
debdt:/tmp# php test.php
replaced

я что-то не так прикрутил?
Bizdelnick, спасибо большое за помощь, честно говоря у меня в голове уже такой винегрет, что меня легко подтолкнуть, только я поеду скорее всего не туда :3
Солнце садилось в море, а люди с неоконченным высшим образованием выбегали оттуда, думая, что море закипит.
Спасибо сказали:

NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Решено: Прошу помощи с регекспом

Сообщение NickLion »

serzh-z, нет, такое не пройдёт: "%%1%% %%2<br/>%%"

Вот лучшее, что получил:

Код: Выделить всё

%%((?!(((?!%%).)*<br/>((?!%%).*))).*?)%%


/ — экранировать при необходимости

Ленивая Бестолочь писал(а):
27.06.2013 14:24
я что-то не так прикрутил?

<br/> а не <br\>
Спасибо сказали:

Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8255
Статус: Маньяк
ОС: Arch, CentOS, Ubuntu

Re: Решено: Прошу помощи с регекспом

Сообщение serzh-z »

Ленивая Бестолоч...
Да вроде всё работает вот так:

Код: Выделить всё

preg_replace("/%%((?!.*?\<br\s\/\>).*?)%%/", "replaced", $input_lines);
Спасибо сказали:

Аватара пользователя
Ленивая Бестолочь
Бывший модератор
Сообщения: 2760
ОС: Debian; gentoo

Re: Решено: Прошу помощи с регекспом

Сообщение Ленивая Бестолочь »

ах тыж ёжик, я у <br /> не тот слешь написал.
кажется вариант Сержа пашет:

Код: Выделить всё

debdt:/tmp# cat test.php
<?php

$string = '%%test<br />%%';

printf ( preg_replace('`%%((?!.*?\<br\s\/\>).*)%%`', 'replaced', $string) . "\n");

?>
debdt:/tmp# php test.php
%test<br />%
debdt:/tmp# vi test.php
debdt:/tmp# cat test.php
<?php

$string = '%%test<xx />%%';

printf ( preg_replace('`%%((?!.*?\<br\s\/\>).*)%%`', 'replaced', $string) . "\n");

?>
debdt:/tmp# php test.php
replaced
debdt:/tmp#

NickLion, ахринеть, китайская грамота для меня )
тоже попробую и сейчас ещё потещу.

serzh-z писал(а):
27.06.2013 14:36
Да вроде всё работает вот так:

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

NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Решено: Прошу помощи с регекспом

Сообщение NickLion »

Ленивая Бестолочь писал(а):
27.06.2013 14:39
NickLion, ахринеть, китайская грамота для меня )
тоже попробую и сейчас ещё потещу.

Там наверное только <br/> → <br\s*/> надо. А то я пробелы не учёл.

Ленивая Бестолочь писал(а):
27.06.2013 14:39
кажется вариант Сержа пашет:

Не отработает, если в одной строке будет несколько комментов:
"%%asdasdbr%% %%asdasd<br />asdf%%" — считает одним, содержащим <br />.
Спасибо сказали:

Аватара пользователя
Ленивая Бестолочь
Бывший модератор
Сообщения: 2760
ОС: Debian; gentoo

Re: Решено: Прошу помощи с регекспом

Сообщение Ленивая Бестолочь »

NickLion
посмотрите, пожалуйста:

Код: Выделить всё

debdt:/tmp# php test.php
replaced
debdt:/tmp# cat test.php
<?php

$string = '%%test<br />%%';

printf ( preg_replace('`%%((?!(((?!%%).)*<br\s*/>((?!%%).*))).*?)%%`', 'replaced', $string) . "\n");

?>
Солнце садилось в море, а люди с неоконченным высшим образованием выбегали оттуда, думая, что море закипит.
Спасибо сказали:

Аватара пользователя
Ленивая Бестолочь
Бывший модератор
Сообщения: 2760
ОС: Debian; gentoo

Re: Решено: Прошу помощи с регекспом

Сообщение Ленивая Бестолочь »

NickLion писал(а):
27.06.2013 14:46
Не отработает, если в одной строке будет несколько комментов:

вообще это важный момент. у меня может быть такая ситуация, например:

Код: Выделить всё

%%111%%<br />222<br />%%222 <br />%%

ожидается что для 111 сработает, а для 222 - нет.
Солнце садилось в море, а люди с неоконченным высшим образованием выбегали оттуда, думая, что море закипит.
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18676
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Решено: Прошу помощи с регекспом

Сообщение Bizdelnick »

Не читал всё, что насоветовали, но при помощи ссылки serzh-z привёл свой вариант к такому, вроде бы рабочему, виду: `%%(?!.*<br \/>).+?%%`
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Решено: Прошу помощи с регекспом

Сообщение NickLion »

Ленивая Бестолочь писал(а):
27.06.2013 14:57
NickLion
посмотрите, пожалуйста:

Да, точно, скобочки забыл:

Код: Выделить всё

%%((?!(((?!%%).)*<br\s*/>((?!%%).)*)).*?)%%

Но это ещё не идеал. Знаю такую проблему (жирным выделил, на что отреагирует):
%%111%% some text %%222 <br /> asd%% yet some text %%333%%
Спасибо сказали:

Аватара пользователя
Ленивая Бестолочь
Бывший модератор
Сообщения: 2760
ОС: Debian; gentoo

Re: Решено: Прошу помощи с регекспом

Сообщение Ленивая Бестолочь »

NickLion, ну вообще я не думаю, что это проблема.
то есть по сути мы считаем, что
1. сначала будут обрабатываться тэги, которые находятся на одной строке (с точки зрения юзера) слева направо
2. затем все оставшиеся по очереди
так что как будто бы это вообще идеально. я ещё потыкаю по-всякому же.
спасибо огромное всем!

update: Да, вроде как всё прекрасно.
Солнце садилось в море, а люди с неоконченным высшим образованием выбегали оттуда, думая, что море закипит.
Спасибо сказали: