Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > PHP: Тексты > Волшебное регулярное выражение |
Автор: CyraxZ 7.8.2013, 18:23 |
Здравствуйте. Есть строка, включающая фрагменты-разделители " AND ", " OR ", " NOT ", "(", ")". Например: program AND fof AND NOT (5 OR 6 OR (8 AND ppp)) Из этой строки мне необходимо получить фрагменты: program fof 5 6 8 ppp Дополнительные условия: а) извлечённые фрагменты не должны иметь пробелов слева или справа (в середине могут) б) регистр фрагментов-разделителей (" AND ", " OR ", " NOT ", "(", ")") неважен в) если в строке фрагментов-разделителей не будет, то регулярное выражение должно вернуть всю исходную строку г) Если рядом стоят OR/AND/NOT и круглая скобка, то между ними пробелов может не быть: ...OR(... ...AND(... ...NOT(... ...(NOT... ...)OR... ...)AND... ...)NOT... ...NOT)... Во всех этих случаях фрагменты OR, AND, NOT, ), ( должны распознаваться как разделители. Каким должно быть регулярное выражение, чтобы извлечь эти фрагменты из строки ? Заранее спасибо. |
Автор: CyraxZ 7.8.2013, 20:49 |
Сабжевое регулярное выражение мне нужно для использования в preg_replace: все отобранные фрагменты будут заменены на другие фрагменты, зависящие от исходных. |
Автор: skyboy 7.8.2013, 21:35 |
смотри. у тебя есть "разделители". ты уже на верном пути. используй http://php.net/preg_split для разбивки строки. и никакое волшебное регулярное выражение не надо: надо только описать твои разделители, добавив по бокам "\s+" для удаления лишних пробелов. P.S. а сами "разделители" тебе точно не надо учитывать? то есть, что AND, что NOT — все равно? если не все равно, то все ж советую подумать над просто последовательным анализом вместо поиска волшебной регулярки: бьешь по пробелам или скобкам, а потом по очереди анализируешь очередной "токен" — и в случае совпадения с NOT/OR/AND делаешь что-то. или не делаешь. |
Автор: CyraxZ 7.8.2013, 22:30 | ||
Эта функция вернёт массив требуемых фрагментов. Но мы потеряем разделители. А мне, как я уже написал, нужно в исходной строке заменить искомые фрагменты на более сложные, при этом оставив на своих местах все разделители. Т.е. исходная строка: program AND fof AND NOT (5 OR 6 OR (8 AND ppp)) Нужно получить: более сложное выраж1 AND более сложное выраж2 AND NOT (более сложное выраж3 OR более сложное выраж4 OR (более сложное выраж5 AND более сложное выраж6)) Если сделать это функцией preg_replace(регВыражение, ...$0..., исходнаяСтрока) было бы здорово. Лаконично и изячно )) |
Автор: skyboy 8.8.2013, 00:21 |
слушай. если у тебя замена безусловная, то сделай просто в несколько заходов: сначала разбить по AND и заменить каждую часть. затем — по OR. и так далее. если замена происходит по результатам выполнения неких функций, то лучше сделать парсинг — разбить на токены. или давай, все ж, полностью задачу, пускай и в упрощенном виде. текущий вариант "заменить что-то на что-то, учитывая разделители" не оправдывает сложности подхода. в моем понимании, решать это регуляркой — это как считать регуляркой корректность закрытия скобок — в некоторых случаях возможно, но зачем городить огород? |
Автор: Gold Dragon 9.8.2013, 07:40 | ||||||||
небольшой набросок
На выходе имеем
и
По индексам мы можем уже спокойно подставлять значения.. Например: - Если второй массив длиннее, значит строка начинается со значения - Если во втором случае [2] и [3] пустые, значит в первом случае [2] и [3] идут друг за другом Добавлено @ 07:42 Но правило нужно доработать, т.к. могут попасться слова, в которых встречается часть, например "android". Здесь нужно проверять ещё дополнительно что перед AND и после нет букв. Что-то как-то так
Добавлено через 8 минут и 57 секунд где-то ошибка в логике в последнем правило.. некоторые строчки пропускает как правильно сказал skyboy, нужно по порядку делать замену. А то усложнение регулярки может привести к тормозам ![]() |
Автор: _zorn_ 14.8.2013, 10:32 | ||||
По моему как раз тот случай ![]() Почему не сделать обычным str_replace ?
Тут могут быть проблемы, если в исходной строке будет например '56', но про это в условии ничего не сказано и я осмелился предположить, что таких ситуаций не случится ![]() |
Автор: krundetz 14.8.2013, 10:56 |
ХМ. А зачем здесь регулярные выражения? Лучше сделать токенайзер, а уже вокруг него построить синтаксический анализатор. В общем теория компиляции. Ключевое слово "Книга Дракона". |
Автор: Gold Dragon 14.8.2013, 21:08 |
это о чём? ![]() Да ладно вам.. Вопрос изначально полный БРЕД! Просто интересная задачка, чисто по практиковаться в регулярках ![]() |
Автор: krundetz 15.8.2013, 10:26 | ||
о теории компиляции.
ну почему же, иногда требуется собственный интерпретатор |