Regex в качестве аргумента командной строки для фильтрации строк с определенным значением - PullRequest
0 голосов
/ 13 марта 2012

Я хочу иметь возможность взять аргумент из командной строки и использовать его как регулярное выражение в моем скрипте для фильтрации строк из моего файла. Простой пример

$ perl script.pl id_4

В script.pl:

...
my $exp = shift;
while(my $line = <$fh){
    if($line =~ /$exp/){
        print $line,"\n";
    }
}
...

Мой настоящий скрипт немного сложнее и выполняет другие манипуляции со строкой для извлечения информации и получения другого результата. Моя проблема в том, что у меня есть ситуации, когда я хочу отфильтровать каждую строку, содержащую "id_4", а не только строки, содержащие "id_4". Обычно это может быть достигнуто

if($line !~ /$exp/)

но, если возможно, я не хочу изменять свой сценарий для принятия более сложного набора аргументов (например, используйте !~, если вторым параметром является "ne", и =~, если нет).

Кто-нибудь может подумать о регулярном выражении, которое я могу использовать (помимо длинного "id_1 | id_2 | id_3 | id_5 ..."), чтобы отфильтровать строки, содержащие одно конкретное значение из множества возможностей? Я боюсь, что я прошу о глупости здесь, и, вероятно, следует просто придерживаться разумного и принять дальнейший аргумент: /.

Ответы [ 2 ]

1 голос
/ 13 марта 2012

Почему выбирают?Есть оба.

my $exp = join "|", grep !/^!/, @ARGV;
my @not = grep /^!/,  @ARGV;
s/^!// for @not;
my $exp_not = join "|", @not;

...
if (( $line =~ $exp ) && ( $line !~ $exp_not )) {
    # do stuff
}

Использование:

perl script.pl orange soda !light !diet
0 голосов
/ 13 марта 2012

Существует способ инвертировать регулярные выражения, так что вы можете делать совпадения типа «все строки, которые не содержат совпадения для subexpr».Без операторов, которые выражают это напрямую (т. Е. Используя только основные операторы регулярных выражений с положительным соответствием), это все еще возможно, но приводит к большим и громоздким регулярным выражениям (возможно, комбинаторному взрыву в размере регулярных выражений).

Дляпростой пример, посмотрите на мой ответ на этот вопрос: как написать регулярное выражение, которое соответствует всему, кроме строки «help».(Это довольно упрощение, что сопоставление привязывается к началу и концу.) Соответствует всем комбинациям букв / цифр, кроме конкретного слова?

В традиционных инструментах Unix есть хаки для ситуаций, когда вы хотитепросто инвертируйте совпадение выражения в целом: grep против grep -v.Или vi: :g/pat/ против :v/pat/ и т. Д. Таким образом, разработчики отказались от реализации сложных операторов регулярных выражений, которые не вписываются в простой подход построения NFA.

Самое простое - этосделать то же самое и иметь соглашение для грубого отрицания: шаблон включения и шаблон исключения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...