Совпадение линий с рисунком n раз в одной строке - PullRequest
4 голосов
/ 15 мая 2011

У меня есть файл, и мне нужно отфильтровать строки, которые имеют (или не имеют) N вхождений шаблона. То есть, если моим шаблоном является буква o и я должен сопоставить строки, где буква o встречается ровно 4 раза, выражение должно соответствовать первой из следующих строк примера, но не другим:

foo foo  
foo  
foo foo foo   

Я могу сделать это с помощью регулярных выражений в vim или sed, awk или любого другого инструмента. Я погуглил и не нашел никого, кто сделал бы подобное. Вероятно, придется сделать скрипт или что-то подобное для разбора каждой строки. Кто-нибудь делал подобное?

Спасибо

Ответы [ 6 ]

5 голосов
/ 15 мая 2011

Вы можете использовать регулярное выражение, как показано ниже:

(?=(.*o){4})(?!(.*o){5,}).*

Regexr - http://regexr.com? 2toro

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

(?=(.*foo){4})(?!(.*foo){5,}).*

Regexr - http://regexr.com? 2tosa

3 голосов
/ 15 мая 2011

Однострочный Perl:

perl -ne 'print if(tr/o/o/ == 4)' foo_file
3 голосов
/ 15 мая 2011
perl -lnwe '@c=$_=~/o/g;if(scalar(@c)==4){print $_}' file_to_parse
2 голосов
/ 15 мая 2011

In awk ...

awk '{ if (gsub(/o/, "o") == 4) print }' # lines that matched
awk '{ if (gsub(/o/, "o") != 4) print }' # lines that didn't

Если вы собираетесь делать это снова и снова с разными шаблонами / количеством совпадений, а шаблон не является регулярным выражениемВы также можете сделать что-то вроде ...

awk -v pattern=o -v matches=4 '{ if (gsub(pattern, pattern) == matches) print }'
0 голосов
/ 15 мая 2011

Если вы хотите написать код, то вы можете создать соответствие строк на основе DFA, или я бы посоветовал вам взглянуть на алгоритм сдвига или сравнения строк, который вы можете легко написать.Затем вы можете ввести строку в соответствующую структуру данных в соответствии с требованиями алгоритма.Прочитайте http://en.wikipedia.org/wiki/Shift_Or_Algorithm для алгоритма сдвига или сопоставления строк.

0 голосов
/ 15 мая 2011

Это возможно, но не просто.

В случае одной буквы будет работать выражение, такое как ^[^o]*o[^o]*o[^o]*o[^o]*o[^o]*$.Он в основном ищет «не о» (ноль или более), за которым следует «о» четыре раза, и допускает дополнительные символы «не о» в конце.

Но более длинные выражения являются проблемойНапример, чтобы не найти слово «foo», вы должны разрешить «f» и «fo», но не «foo».Таким образом, чтобы найти строку с ровно в два раза «foo», вы должны разрешить строку «ffofofoofoffoffoofoffofofofo», которую не так просто определить.1008 *, который допускает "f" и "fo" и другие вещи, но не "foo".Но вы можете видеть, как это может раздражать, если слово длиннее и вам нужно сопоставить его четыре раза.

...