Здравствуйте!Вначале опишу задачу.
Нужно найти соответствие строки по следующему макрокоду:
((НЕ abc)И(НЕ def)И(НЕ ghi))xyzТо есть, строки, удовлетворяющие регвыру, могут выглядеть так:
jklxyz
cbaxyz
adgxyzСтроки, не удовлетворяющие регвыру, выглядят так:
abcxyz
defxyz
ghixyzЗадача: нужно написать выражение, повторяющее поведение приведенного выше макрокода.
PS:
Дело в том, что я не понимаю две вещи:
1. Как в регвырах написать "несоответсвие подстроке". Несоответсвие символу или несоответсвие диапазону символов - это понятно как делать. А как сделать несоответсвие подстроке, например, что-то типа !(abc) - непонятно.
2. Как связывать куски шаблонов через логическую И - тоже непонятно. В регвырах есть только операция ИЛИ.
> Вначале опишу задачу.
> Нужно найти соответствие строки по следующему макрокоду:
>((НЕ abc)И(НЕ def)И(НЕ ghi))xyzДенег-то сколько?...
>> Вначале опишу задачу.
>> Нужно найти соответствие строки по следующему макрокоду:
>>((НЕ abc)И(НЕ def)И(НЕ ghi))xyz
> Денег-то сколько?...Чего?
>> Денег-то сколько?...
> Чего?Ну, ты же работу предагаешь? Решение никому не нужной задачи неподходящими средствами.
> Ну, ты же работу предагаешь?Составить регвыр - это уже работой зовётся?
> Решение никому не нужной задачи неподходящими средствами.Поиск подстроки в строке по условию. Какое другое средство применять вместо регвыра?
>> Ну, ты же работу предагаешь?
> Составить регвыр - это уже работой зовётся?
>> Решение никому не нужной задачи неподходящими средствами.
> Поиск подстроки в строке по условию. Какое другое средство применять вместо регвыра?Чё ж ты сразу-то молчал?! Хошь регексп, на тебе регексп!!
$ cat <<EO |awk 'match($0,"(...)xyz",a)&&a[1]!~"abc|def|ghi"'
> jklxyz
> cbaxyz
> adgxyz
>
> abcxyz
> defxyz
> ghixyz
>
> EOjklxyz
cbaxyz
adgxyz
$ _+++Да, я тоже буду читить. И решать криво поставленное, да! Никто, никто ж не заметит!!
Язык не назван, значит будет perl:
m/(?<!abc)(?<!def)(?<!ghi)xyz/Внутри (?<!...) допустимы только строки постоянной длины, (?<!ab*c) не прокатит.
Andrey Mitrofanov, кончай ворчать, иногда ведь мозг напрячь приятно :-) Хоть и на полминуты, хоть и на пустяшную задачку, хоть и бесплатно.
>значит будет perl:
> Внутри (?<!...) допустимы только
> Andrey Mitrofanov, кончай ворчать, иногда ведь мозг напрячь приятно :-) Хоть и
> на полминуты, хоть и на пустяшную задачку, хоть и бесплатно.:))) Посто на обычном грепе "решение не поместилось на полях этого трактата"(ТМ) -- писать было б долго-нудно-и-противно. И, да, я этих ваших перлов не знаю, поэтому... то ли ты считил, то ли я слил...
> Язык не назван, значит будет perl:
>m/(?<!abc)(?<!def)(?<!ghi)xyz/
> Внутри (?<!...) допустимы только строки постоянной длины, (?<!ab*c) не прокатит.Вот, тут и вылезла проблема.
Оказывается, "отрицательные" строки могут быть разной длинны. То есть, набор не "abc" "def" "ghi", но и, например, "a" "bc" "def".
Что делать в этом случае?
>> Внутри (?<!...) допустимы только строки постоянной длины, (?<!ab*c) не прокатит.
> Вот, тут и вылезла проблема.
> Оказывается, "отрицательные" строки могут быть разной длинны. То есть, набор не
> "abc" "def" "ghi", но и, например, "a" "bc" "def".
> Что делать в этом случае?Давай-ка сюда полное условие задачи, а то так можно долго рассусоливать.
PS. Правильно поставленный вопрос — уже половина ответа. (кто-то умный сказал)
> Давай-ка сюда полное условие задачи, а то так можно долго рассусоливать.
> PS. Правильно поставленный вопрос — уже половина ответа. (кто-то умный сказал)Полное условие слишком большое. Я специально сделал примитивную задачу, чтобы решить основной вопрос поиска таких подстрок. На самом деле там конечно не abc-def-ghi, а более другие подстроки и количество их больше, размер разный. Просто когда придумывал задачу, даже не думал, что может возникнуть ограничение на одинаковость длины подстрок.
Поэтому, правильнее задачу на макроязыке можно переформулировать так:
((НЕ a)И(НЕ bc)И(НЕ def))xyzНа тестовых данных:
abcxyz
defxyz
ghixyz
aaaxyz
bbbxyz
bxyz
kkxyzДолжны быть выбраны строки:
ghixyz
bbbxyz
bxyz
kkxyz
> а более другие подстроки и количество их больше, размер разный. Просто
> когда придумывал задачу, даже не думал, что может возникнуть ограничение на
> одинаковость длины подстрок.Нет такого ограничения. Как я писал выше, есть лишь условие, что выражение внутри (?<!...) должно быть постоянной длины.
Тут уж 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
> Поэтому, правильнее задачу на макроязыке можно переформулировать так:
>((НЕ 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)
> (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...
>> (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) ) = ?
> Митрофаныч, а ты наизусть помнишь де Моргана и другие логические комбинации?Чё там помнить-то? Название, "де Моргана", в гугле за минуту нашёл...
> !( !(!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|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)
...
ладно, забей, мож и я где-то запутался. %)
> регвыруХватит, блин, аж глаза режет. Регэксп в крайнем случае.
Для перла и, наверное, пкре:
/(?<!abc|def|ghi)xyz/
> Для перла и, наверное, пкре:
> /(?<!abc|def|ghi)xyz/Да, для PCRE.
Выше написал - что делать в случае разной длинны "отрицательных" шаблонов?
Ответ, как всегда, в /dev/random:$ dd if=/dev/random bs=64 count=1Там много интересного, почитай ;)
grep{$a=$_;!grep{$_}map{$a=~/(?<=$_)xyz/}qw/a bc def/}<>;#wtf??
$ _