LINUX.ORG.RU

[Регулярные выражения] Как совмещать шаблоны поиска через И, ИЛИ, НЕ?

 


0

1

Здравствуйте!

Вначале опишу задачу.

Нужно найти соответствие строки по следующему макрокоду:

((НЕ abc)И(НЕ def)И(НЕ ghi))xyz

То есть, строки, удовлетворяющие регвыру, могут выглядеть так:

jklxyz
cbaxyz
adgxyz

Строки, не удовлетворяющие регвыру, выглядят так:

abcxyz
defxyz
ghixyz

Задача: нужно написать выражение, повторяющее поведение приведенного выше макрокода.

PS:

Дело в том, что я не понимаю две вещи:

1. Как в регвырах написать «несоответсвие подстроке». Несоответсвие символу или несоответсвие диапазону символов - это понятно как делать. А как сделать несоответсвие подстроке, например, что-то типа !(abc) - непонятно.

2. Как связывать куски шаблонов через логическую И - тоже непонятно. В регвырах есть только операция ИЛИ.

а для баловства с ((НЕ abc)И(НЕ def)И(НЕ ghi)) - читать про днф и кнф, и как одно в другое преобразовать

ananas ★★★★★
()
Ответ на: комментарий от ananas

> man 7 regex

Спасибо вам большое за ответ.

днф и кнф

Напишите правильные аббревиатуры или дайте ссылку на эту йнх.

webhamster
() автор топика
Ответ на: комментарий от ananas

> дизъюнктивная и конъюнктивная нормальные формы булевых функций

Замечательно. Покажите регвыр (без хаков с разбивкой подстрок «abc», «def», «ghi» на символы), и вопрос будет исчерпан.

webhamster
() автор топика
Ответ на: комментарий от webhamster

> И еще - покажите регвыр, удовлетворяющий этой простой (для знащего человека) задачи.

для чего? в смысле - для какого иснтрумента?

ananas ★★★★★
()

Говоря строго, задача выходит за пределы регулярных языков. Тут нужно использовать не регулярные выражения (в строгом смысле слова).

anarquista ★★★★★
()
Ответ на: комментарий от webhamster

(!a и !b) = !(a или b)

ananas это имел в виду, говоря о днф и кнф

adriano32 ★★★
()
Ответ на: комментарий от kiverattes

> Много килочасов думал?

всю жизнь. и продолжаю. и единственное, что вынес - если человек прочитал доку, убедился, что в данном конкретном случае подобная задача должна решаться при поможи внешних инструментов, так как нужные механизмы в regex-ах не предусмотрены, но тем не менее задает вопрос - он сам понимаешь кто

ananas ★★★★★
()
Ответ на: комментарий от ananas

>> И еще - покажите регвыр, удовлетворяющий этой простой (для знащего человека) задачи.

для чего? в смысле - для какого иснтрумента?

Для Perl Compatible Regular Expressions

webhamster
() автор топика
Ответ на: комментарий от anarquista

> Тут нужно использовать не регулярные выражения (в строгом смысле слова).

тут нужно использовать несколько регулярных выражений, и объединять их в булеву функцию внешними средствами

ananas ★★★★★
()
Ответ на: комментарий от anarquista

То есть, именно данная-то задача вполне «регулярная», но использование отрицание применительно к подвыражениям — нет.

anarquista ★★★★★
()
Ответ на: комментарий от ananas

> в данном конкретном случае подобная задача должна решаться при поможи внешних инструментов, так как нужные механизмы в regex-ах не предусмотрены

В preg же есть lookbehind с отрицанием. ТС не уточнял, какие именно регулярки имеет ввиду.

geekless ★★
()
Ответ на: комментарий от webhamster

проверяешь на "(abc|def|ghi)xyz", и если НЕ совпадает - строка твоя. на сях писать пример лень, думаю, что как оценить код возврата - сам знаешь

ananas ★★★★★
()
Ответ на: комментарий от geekless

«Регулярный язык», «регулярное выражение» — понятия вполне определенные. Двух мнений быть не может.

Да, часто эти термины используют для обозначения чего-то совсем другого (perl). Тогда необходимо указывать это явно.

Занудство, но это так.

anarquista ★★★★★
()
Ответ на: комментарий от anarquista

> «Регулярный язык», «регулярное выражение» — понятия вполне определенные.

Я в курсе. Что не мешает называть preg регулярками, хоть они и являются на самом деле надмножеством для регулярных выражений. Сабжевая ОС этого форума тоже по-настоящему не Linux называется, в конце концов.

Занудство, но это так.

Истинно занудство.

geekless ★★
()
Ответ на: комментарий от ananas

> за такое маленьким копчики массируют

У меня иной опыт. А про гугл и ман и без вас известно.

kiverattes ★☆
()

Лол, паттерны Снобола :)

buddhist ★★★★★
()
Ответ на: комментарий от geekless

Обманываете. Прекрасно работает:

Ну как же:

Вы написали: (?<!(abc|def|ghi))xyz

А нужно было: ...(?<!(abc|def|ghi))xyz


Но тут вылезает проблема: это выражение подходит для набора строк фиксированной длинны. А если исключаемые строки разной длинны?

Ну, то есть, если у нас вместо «abc», «def», «hgi», будет «a», «bc», «def», то как тогда?

Я попробовал

.+(?<!(a|bc|def))xyz

и

(.+)(?<!(a|bc|def))xyz

Оба выражения дают ошибку:

preg_match_all() [function.preg-match-all]: Compilation failed: lookbehind assertion is not fixed length at offset XX

Что делать?

webhamster
() автор топика
Ответ на: комментарий от webhamster

Ну как же:

Вы написали: (?<!(abc|def|ghi))xyz

А нужно было: ...(?<!(abc|def|ghi))xyz

А сами вы головой подумать не в состоянии?

Но тут вылезает проблема: это выражение подходит для набора строк фиксированной длинны. А если исключаемые строки разной длинны?

Граммарнаци посылают вам лучи ненависти.

Что делать?

Прочитать мануал.

Например.

geekless ★★
()
Ответ на: комментарий от geekless

> Например.

Не понял этого примера. Там решается что-то другое. Еще раз прочитайте про разную длинну:

http://www.linux.org.ru/jump-message.jsp?msgid=6676128&cid=6676437

Имеется в виду не разная длинна искомого текста, а разная длинна «отрицательных шаблонов».

webhamster
() автор топика
Ответ на: комментарий от webhamster

> Имеется в виду не разная длинна искомого текста, а разная длинна «отрицательных шаблонов».

Ссылку я уже давал.

Не понял этого примера.

RTFM

geekless ★★
()
Ответ на: комментарий от geekless

Ссылку я уже давал.

Я спросил: если у нас вместо «abc», «def», «hgi», будет «a», «bc», «def», то как тогда? Другими словами:

((НЕ a)И(НЕ bc)И(НЕ def))xyz

По вашей ссылке следущее выражение:

/...(?<!(abc|def|ghi))(?<!a)(?<!b)xyz/

Оно явно не решает данную задачу.

webhamster
() автор топика
Ответ на: комментарий от geekless

Втыкать в пример до посинения. До позеленения даже.

Еще раз. Условие на макроязыке:

((НЕ a)И(НЕ bc)И(НЕ def))xyz

Ваш регвыр:

/...(?<!(abc|def|ghi))(?<!a)(?<!b)xyz/

Проверяемые строки:

abcxyz
defxyz
ghixyz
aaaxyz
bbbxyz

Результат: Совпадений не найдено.

Правильный результат: строки ghixyz и bbbxyz должны быть найдены, согласно условию.

Вывод: вы что-то забыли убрать, и что-то забыли дописать.

webhamster
() автор топика
Ответ на: комментарий от webhamster

> Еще раз. Условие на макроязыке:

Я что, где-то писал, что этот пример соответствует твоему условию?

Я тебе показал, как делать несколько lookbehind разной длины. Дальше сам кури мануал и делай, что тебе надо. А то может мне еще и деньги кто-нибудь поплатит за код, который ты пишешь?

Мало пример показать, надо еще разжевать и в рот положить, да весь мануал пересказать своими словами. Совсем обнаглели.

geekless ★★
()
Ответ на: комментарий от geekless

> Дальше сам кури мануал и делай, что тебе надо. А то может мне еще и деньги кто-нибудь поплатит за код, который ты пишешь? Мало пример показать, надо еще разжевать и в рот положить, да весь мануал пересказать своими словами. Совсем обнаглели.

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

webhamster
() автор топика
Ответ на: комментарий от geekless

Жалко конечно. Особенно когда гуру то неполный кусок регвыра покажут, то регвыр не для конкретной задачи напишут и будут говорить что все правильно.

webhamster
() автор топика
Ответ на: комментарий от geekless

Кстати, если ты имел в виду что-то типа такого:

/...(?<!(a))(?<!bc)(?<!def)xyz/

то это выражение не будет работать на коротких строках. То есть, для данных:

abcxyz
defxyz
ghixyz
aaaxyz
bbbxyz
bxyz
kkxyz

будут найдены «ghixyz» и «bbbxyz».

А «bxyz» и «kkxyz» найдены не будут.

webhamster
() автор топика
Ответ на: комментарий от webhamster

> Ты бесполезен для общества.

Вот оно чо. Пойду впаду в депрессию. :D

geekless ★★
()
Ответ на: комментарий от webhamster

/.*?(?:(?:a|bc|def)xyz(*PRUNE)(*FAIL)|xyz)/

perldoc perlre на предмет PRUNE (там есть ворнинг в начале раздела). Но это извращение, ананас дело говорит. Кстати, этот ваш regexpr.ru выдаёт $&, а не $_, что может совпадать, а может и не совпадать с запросом топикстартера (в perldoc perlvar описано, что значат эти закорючки).

anonymous
()
Ответ на: комментарий от webhamster

> Ты бесполезен для общества.

Бесполезен здесь ты.

Нормальный программист за полчаса написал бы Lisp DSL, который бы решал проблему полностью и исчерпывающе. Но ты, предпочитаешь ковыряться в окаменелом говне мамонта aka regexp и выносить мозг окружающим. Потому что ты — быдло-monkey-кодер.

Кстати, что это ты там такое супер-пупер-полезное пишешь? Не твоя ли конторка HamsterSoft, которую недавно прилюдно озалупили?

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.