Perl, регулярное выражение, извлечение данных из строки - PullRequest
0 голосов
/ 09 апреля 2010

Я пытаюсь извлечь часть строки с помощью perl

use strict; 
use warnings;


# Set path for my.txt and extract datadir
my @myfile = "C:\backups\MySQL\my.txt";
my @datadir = "";

open READMYFILE, @myfile or die "Error, my.txt not found.\n";
    while (<READMYFILE>) {
        # Read file and extract DataDir path
        if (/C:\backups/gi) {
        push @datadir, $_;
        }
    }

# ensure the path was found
print @datadir . " \n";

Сначала я пытаюсь указать местоположение файла my.txt. Затем я пытаюсь прочитать его и вытянуть часть строки с помощью регулярного выражения. Я получаю ошибку:

Нераспознанный побег \ м прошел по номеру 1130.пл 17.

Я взглянул на Как я могу получить несколько строк после совпадающей строки в Perl? , чтобы получить представление о том, как прочитать файл и сопоставить строку внутри него, однако я не уверен на 100% Я делаю это правильно или наилучшим образом. Я также, кажется, выдаю ошибку:

Ошибка, my.txt не найден.

Но файл существует в папке C: \ backups \ MySQL \

Ответы [ 6 ]

4 голосов
/ 09 апреля 2010

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

use strict; 
use warnings;
# For pretty dumping of arrays and what not.
use Data::Dumper;

# Use single quotes so you don't have to worry about escaping '\'s.
# Use a scalar ($) instead of an array(@) for storing the string.
my $myfile = 'C:\backups\MySQL\my.txt';

# No need to initialize the array.
my @datadir;

# I believe using a scalar is preferred for file handles.
# $! will contain the error if we couldn't open the file.
open(my $readmyfile, $myfile) or die "error opening: $!";

while (<$readmyfile>) {
    # You must escape '\'s by doubling them.
    # If you are just testing to see if the line contains 'c:\backups' you do not
    # need /g for the regex. /g is for repeating matches
    if (/C:\\backups/i) {
        push(@datadir, $_);
    }
}

# Data::Dumper would be better for dumping the array for debugging.
# Dumper wants a reference to the array.
print Dumper(\@datadir);

Обновление:

Если вы ссылаетесь на вывод из Data :: Dumper, он просто для красивого представления массива. Если вам нужен специально отформатированный вывод, вам придется его кодировать. Начало будет:

print "$_\n" for (@datadir);
4 голосов
/ 09 апреля 2010

Когда Perl видит строку "C:\backups\MySQL\my.txt", он пытается проанализировать любые escape-последовательности, такие как \n. Но когда он видит \m в \my.txt, это нераспознанная escape-последовательность, отсюда и ошибка.

Один из способов исправить это - правильно избежать обратной косой черты: "C:\\backups\\MySQL\\my.txt". Другой способ исправить это - использовать одинарные кавычки вместо двойных: 'C:\backups\MySQL\my.txt'. И все же другой способ заключается в использовании конструкции q(): q(C:\backups\MySQL\my.txt).

1 голос
/ 09 апреля 2010

Как уже говорили другие люди, часть проблемы заключается в использовании " " вместо ' ' типа цитирования. Я всегда стараюсь использовать ' ', если не знаю, что мне нужно включить escape или интерполировать переменную. Вот несколько подводных камней

    use 5.10.0 ;
    use warnings ;

    say "file is c:\mydir" ;
    say "please pay $100 ";
    say "on VMS the system directory is sys$system" ;
    say "see you @5 ";

С двойными кавычками

    Unrecognized escape \m passed through at (eval 1) line 2.
    Possible unintended interpolation of @5 in string at (eval 1) line 5.
    file is c:mydir
    Use of uninitialized value $100 in concatenation (.) or string at (eval 1) line 3.
    please pay
    Use of uninitialized value $system in concatenation (.) or string at (eval 1) line 4.
    on VMS the system directory is sys
    see you

С одинарными кавычками

    file is c:\mydir
    please pay $100
    on VMS the system directory is sys$system
    see you @5
1 голос
/ 09 апреля 2010

Файл не найден, потому что вы передаете массив в open, когда он ожидает скаляр, поэтому я предполагаю, что массив оценивается в скалярном контексте, а не как список, так что вы на самом деле Говоря Perl, попробуйте открыть файл с именем «1» вместо файла «my.txt».

Попробуйте что-то вроде этого:

my $a = 'filename';
open FH, $a or die "Error, could not open $a: $!";
...
1 голос
/ 09 апреля 2010

Разве вы не должны использовать $myfile вместо @myfile? Последний дает вам массив, и, поскольку вы ссылаетесь на него в скалярном контексте, он получает разыменование (поэтому он фактически пытается открыть «файл», называемый чем-то вроде ARRAY (0xdeadbeef) вместо фактического имени файла).

1 голос
/ 09 апреля 2010

Использовать косые черты вместо обратных.

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