Как правильно остановить и запустить интерполяцию метасимволов в регулярных выражениях в Perl - PullRequest
0 голосов
/ 19 декабря 2018

Редактирование, чтобы быть более кратким, простите.

Мне нужно иметь возможность извлекать из массива, используя строку, которая может содержать один из следующих символов: '.', '+', '/', '-'.Строка будет получена от пользователя.Массив содержит каждую строку файла, который я просматриваю (я сжимаю файл в массив, чтобы не оставлять его открытым, пока пользователь взаимодействует с программой, потому что он находится в cron, и я не хочу его иметьopen, когда запускается cron), и каждая строка имеет уникальный идентификатор, который является основой для строки поиска, используемой в регулярном выражении.Приведенный ниже код показывает оператор grep, который я использую, и я использую OUR и MY в своих программах, чтобы сделать переменные, к которым я хочу получить доступ, во всех пространствах имен, а те, которые я использую только в подпрограммах, - нет.Если вы хотите попытаться повторить проблему

#!/usr/bin/perl -w

use strict;
use Switch;
use Data::Dumper;

our $pgm_path = "/tmp/";
our $device_info = "";

our @new_filetype1 = ();
our @new_filetype2 = ();
our @dev_info = ();
our @pgm_files = ();

our %arch_rtgs = ();

our $file = "/path/file.csv";
open my $fh, '<', $file or die "Couldn't open $file!\n";
chomp(our @source_file = <$fh>);
close $fh;

print "Please enter the device name:\n";
chomp(our $dev = <STDIN>);

while ($device_info eq "") {
    # Grep the device info from the sms file
    my @sms_device = grep(/\Q$dev\E/, @source_file);
    if (scalar(@sms_device) > 1) {
        my $which_dup = find_the_duplicate(\@sms_device);
        if ($which_dup eq "program") {
            print "\n-> $sms_dev <- must be a program name instead of a device name." .
            "\nChoose the device from the list you are working on, specifically.\n";
            foreach my $fix(@sms_device) {
                my @fix_array = split(',', $fix);
                print "$fix_array[1]\n";
                undef @fix_array;
            }
            chomp($sms_dev = <STDIN>);
            } else { $device_info = $which_dup; }
        } elsif (scalar(@sms_device) == 1) { 
            ($device_info) = @sms_device;
            @sms_device = ();
        }
}

Когда я пытаюсь код с привязкой:

my @sms_device = grep(/\Q$dev\E^/, @source_file);

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

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

Ответы [ 2 ]

0 голосов
/ 19 декабря 2018

Идентификатор устройства с последующим началом строки?/\Q$dev\E^/ не имеет смысла.Вы хотите, чтобы перед идентификатором устройства начиналось начало строки, а затем - конец строки.

grep { /^\Q$dev\E\z/ }

Еще лучше, давайте не будем разгонять механизм регулярных выражений.

grep { $_ eq $dev }

Например,

$ perl -e'my $dev = "ccc"; CORE::say for grep { /^\Q$dev\E\z/ } qw( accc ccc ccce );'
ccc

$ perl -e'my $dev = "ccc"; CORE::say for grep { $_ eq $dev } qw( accc ccc ccce );'
ccc
0 голосов
/ 19 декабря 2018

Я бы использовал quotemeta.Вот пример сравнения:

my $regexp = '\t';
my $metaxp = quotemeta ($regexp);

while (<DATA>) {
  print "match \$regexp - $_" if /$regexp/;
  print "match \$metaxp - $_" if /$metaxp/;
}

__DATA__
This \t is not a tab
This    is a tab

(буквально во второй строке есть вкладка)

Мета-версия будет соответствовать строке 1, так как оказалось "\ t"в сущности "\ t", и немета (оригинальная) версия будет соответствовать строке 2, что предполагает, что вы ищете вкладку.

match $metaxp - This \t is not a tab
match $regexp - This    is a tab

Надеюсь, вы меня поняли.

Я думаю, что добавление $regexp = quotemeta ($regexp) (или выполнение этого при захвате стандартного ввода) должно отвечать вашим потребностям.

...