URL: https://www.opennet.ru/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9228
[ Назад ]

Исходное сообщение
"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"

Отправлено xintrea , 29-Авг-11 15:57 
Здравствуйте!

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

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

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

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

jklxyz
cbaxyz
adgxyz

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

abcxyz
defxyz
ghixyz

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

PS:

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

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

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


Содержание

Сообщения в этом обсуждении
"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено Andrey Mitrofanov , 29-Авг-11 16:03 
> Вначале опишу задачу.
> Нужно найти соответствие строки по следующему макрокоду:
>
((НЕ abc)И(НЕ def)И(НЕ ghi))xyz

Денег-то сколько?...


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено xintrea , 29-Авг-11 16:16 
>> Вначале опишу задачу.
>> Нужно найти соответствие строки по следующему макрокоду:
>>
((НЕ abc)И(НЕ def)И(НЕ ghi))xyz

> Денег-то сколько?...

Чего?


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено Andrey Mitrofanov , 29-Авг-11 16:35 
>> Денег-то сколько?...
> Чего?

Ну, ты же работу предагаешь? Решение никому не нужной задачи неподходящими средствами.


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено xintrea , 29-Авг-11 16:58 
> Ну, ты же работу предагаешь?

Составить регвыр - это уже работой зовётся?


> Решение никому не нужной задачи неподходящими средствами.

Поиск подстроки в строке по условию. Какое другое средство применять вместо регвыра?


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено Andrey Mitrofanov , 29-Авг-11 17:22 
>> Ну, ты же работу предагаешь?
> Составить регвыр - это уже работой зовётся?
>> Решение никому не нужной задачи неподходящими средствами.
> Поиск подстроки в строке по условию. Какое другое средство применять вместо регвыра?

Чё ж ты сразу-то молчал?! Хошь регексп, на тебе регексп!!

$ cat <<EO |awk 'match($0,"(...)xyz",a)&&a[1]!~"abc|def|ghi"'
> jklxyz
> cbaxyz
> adgxyz
>
> abcxyz
> defxyz
> ghixyz
>
> EO

jklxyz
cbaxyz
adgxyz
$ _

+++Да, я тоже буду читить. И решать криво поставленное, да! Никто, никто ж не заметит!!


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено XAnder , 29-Авг-11 17:08 
Язык не назван, значит будет perl:

m/(?<!abc)(?<!def)(?<!ghi)xyz/

Внутри (?<!...) допустимы только строки постоянной длины, (?<!ab*c) не прокатит.

Andrey Mitrofanov, кончай ворчать, иногда ведь мозг напрячь приятно :-) Хоть и на полминуты, хоть и на пустяшную задачку, хоть и бесплатно.


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено Andrey Mitrofanov , 29-Авг-11 17:13 
>значит будет perl:
> Внутри (?<!...) допустимы только
> Andrey Mitrofanov, кончай ворчать, иногда ведь мозг напрячь приятно :-) Хоть и
> на полминуты, хоть и на пустяшную задачку, хоть и бесплатно.

:))) Посто на обычном грепе "решение не поместилось на полях этого трактата"(ТМ) -- писать было б долго-нудно-и-противно. И, да, я этих ваших перлов не знаю, поэтому... то ли ты считил, то ли я слил...


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено xintrea , 29-Авг-11 17:24 
> Язык не назван, значит будет perl:
>
m/(?<!abc)(?<!def)(?<!ghi)xyz/

> Внутри (?<!...) допустимы только строки постоянной длины, (?<!ab*c) не прокатит.

Вот, тут и вылезла проблема.

Оказывается, "отрицательные" строки могут быть разной длинны.  То есть, набор не "abc" "def" "ghi", но и, например, "a" "bc" "def".

Что делать в этом случае?



"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено XAnder , 29-Авг-11 17:59 
>> Внутри (?<!...) допустимы только строки постоянной длины, (?<!ab*c) не прокатит.
> Вот, тут и вылезла проблема.
> Оказывается, "отрицательные" строки могут быть разной длинны.  То есть, набор не
> "abc" "def" "ghi", но и, например, "a" "bc" "def".
> Что делать в этом случае?

Давай-ка сюда полное условие задачи, а то так можно долго рассусоливать.

PS. Правильно поставленный вопрос — уже половина ответа. (кто-то умный сказал)


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено xintrea , 29-Авг-11 19:29 
> Давай-ка сюда полное условие задачи, а то так можно долго рассусоливать.
> PS. Правильно поставленный вопрос — уже половина ответа. (кто-то умный сказал)

Полное условие слишком большое. Я специально сделал примитивную задачу, чтобы решить основной вопрос поиска таких подстрок. На самом деле там конечно не abc-def-ghi, а более другие подстроки и количество их больше, размер разный. Просто когда придумывал задачу, даже не думал, что может возникнуть ограничение на одинаковость длины подстрок.

Поэтому, правильнее задачу на макроязыке можно переформулировать так:

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

На тестовых данных:

abcxyz
defxyz
ghixyz
aaaxyz
bbbxyz
bxyz
kkxyz

Должны быть выбраны строки:

ghixyz
bbbxyz
bxyz
kkxyz


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено XAnder , 30-Авг-11 08:37 
> а более другие подстроки и количество их больше, размер разный. Просто
> когда придумывал задачу, даже не думал, что может возникнуть ограничение на
> одинаковость длины подстрок.

Нет такого ограничения. Как я писал выше, есть лишь условие, что выражение внутри (?<!...) должно быть постоянной длины.

Тут уж man perlre или http://perldoc.perl.org/perlre.html на предмет "Extended Patterns".

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

Здесь все строки постоянной длины.

> Должны быть выбраны строки:
> ghixyz
> bbbxyz
> bxyz
> kkxyz

$ perl -e 'for (qw/abcxyz defxyz ghixyz aaaxyz bbbxyz bxyz kkxyz/) {print "$_\n" if m/(?<!a)(?<!bc)(?<!def)xyz/}'
ghixyz
bbbxyz
bxyz
kkxyz


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено BJyyewsrhbe tud , 30-Сен-11 22:29 
> Поэтому, правильнее задачу на макроязыке можно переформулировать так:
>
((НЕ a)И(НЕ bc)И(НЕ def))xyz

Да будет известно, что

(NOT A) AND (NOT B) AND  (NOT C) AND (NOT D) AND ... (NOT Z) == NOT (A AND B AND C AND D AND ... AND Z)  


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено Andrey Mitrofanov , 03-Окт-11 14:10 
> (NOT A) AND (NOT B) AND  (NOT C) AND (NOT
> D) AND ... (NOT Z) == NOT (A AND B AND
> C AND D AND ... AND Z)

Нет, садись - двойка. http://ru.wikipedia.org/wiki/%D0%97%D0%B...


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено pavlinux , 08-Ноя-11 05:56 
>> (NOT A) AND (NOT B) AND  (NOT C) AND (NOT
>> D) AND ... (NOT Z) == NOT (A AND B AND
>> C AND D AND ... AND Z)
> Нет, садись - двойка. http://ru.wikipedia.org/wiki/%D0%97%D0%B...

Митрофаныч, а ты наизусть помнишь де Моргана и другие логические комбинации?  


!( !(!A & !B & !С)  | !( !D & !E & !F)  | !( !G & !H & !K)  )  = ?


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено Andrey Mitrofanov , 08-Ноя-11 18:15 
> Митрофаныч, а ты наизусть помнишь де Моргана и другие логические комбинации?

Чё там помнить-то? Название, "де Моргана", в гугле за минуту нашёл...

> !( !(!A & !B & !С)  | !( !D & !E & !F) | !( !G & !H & !K) )  = ?

= !( A|B|C | D|E|F | G|H|K )
= !A & !B & !C & ... & !K

Хотя, глядя на результат, над был, нверное, снгачала внешнюю скобку "крутить" -
= !!(!A & !B & !С) & !!( !D & !E & !F) & !!( !G & !H & !K)
= !A & !B & !С & !D & !E & !F & !G & !H & !K

Удовлетворён? B)


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено pavlinux , 08-Ноя-11 22:51 
>[оверквотинг удален]
> Чё там помнить-то? Название, "де Моргана", в гугле за минуту нашёл...
>> !( !(!A & !B & !С)  | !( !D & !E & !F) | !( !G & !H & !K) )  = ?
> = !( A|B|C | D|E|F | G|H|K )
> = !A & !B & !C & ... & !K
> Хотя, глядя на результат, над был, нверное, снгачала внешнюю скобку "крутить" -
> = !!(!A & !B & !С) & !!( !D & !E &
> !F) & !!( !G & !H & !K)
> = !A & !B & !С & !D & !E & !F
> & !G & !H & !K
> Удовлетворён? B)

!( !(!A & !B & !С)  | !( !D & !E & !F)  | !( !G & !H & !K)  )  =

внешняя скобка раскрывается как

!(!A & !B & !С) & !( !D & !E & !F) & !( !G & !H & !K)

потом тройки

!( !A & !B & !С ) == A | B | C  
!( !D & !E & !F ) == D | E | F
!( !G & !H & !K ) == G | H | K

получаем

( A | B | C  ) &  (D | E | F)  & (G | H | K)

...
ладно, забей, мож и я где-то запутался. %)


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено anonymous , 29-Авг-11 17:14 
> регвыру

Хватит, блин, аж глаза режет. Регэксп в крайнем случае.

Для перла и, наверное, пкре:
/(?<!abc|def|ghi)xyz/


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено xintrea , 29-Авг-11 17:26 
> Для перла и, наверное, пкре:
> /(?<!abc|def|ghi)xyz/

Да, для PCRE.

Выше написал - что делать в случае разной длинны "отрицательных" шаблонов?


"Регулярные выражения: совмещение шаблонов через И, ИЛИ, НЕ"
Отправлено anonymous , 29-Авг-11 23:51 
Ответ, как всегда, в /dev/random:
$ dd if=/dev/random bs=64 count=1
grep{$a=$_;!grep{$_}map{$a=~/(?<=$_)xyz/}qw/a bc def/}<>;#wtf??
$ _
Там много интересного, почитай ;)