Как я могу заставить это Perl регулярное выражение работать? - PullRequest
4 голосов
/ 10 июня 2010

У меня есть эта строка

/Od /D "WIN32" /D "_DEBUG" /FD /EHa /MDd /Fo"Debug" /Fd"Debug\vc80.pdb" /W3 /c /Zi /clr /TP .\main.cpp"

И я хочу извлечь .\main.cpp. Я думал, что следующее поможет:

if($string =~ /.*\s+(.*)$/i) {
 print "matched ",$1,"\n";
}

потому что это же регулярное выражение работает в Ruby и извлекает необходимую мне строку. Как я могу заставить его работать?

РЕДАКТИРОВАТЬ: вот как я настраиваю свою строку:

for(find_indexes(\@lines,"/MDd")) {
    my $actual_line = $lines[$_];
    $actual_line    = modify($actual_line,$additional_defs);
}

find_indexes возвращает индексы строк, соответствующие любому из параметров, следующих за массивом ref. Подпрограмма modify вернет измененную версию отправленной ей строки, содержащей некоторые дополнительные определения.

РЕДАКТИРОВАТЬ2: вот подпункт modify:

sub modify {
    my $string      = shift;
    chomp($string);
    my @defines     = @_;
    if($string =~ /.*\s+(\".*?)$/) {
        my $match = $1;
        print "match is $match";
        my $string_copy = $string;
        print "|$string_copy|\n";
    }
}

Сабвуфер не завершен, так как я не смог заставить его работать так, как должен. Я добавил дополнительную цитату в группу захвата, чтобы она соответствовала названию. Что-то странное происходит, хотя, я ожидаю, что печать $string_copy напечатает оригинальную строку, заключенную в |. Однако я получаю только ведущую трубу, а не конечную. Я подумал, что, возможно, Perl неправильно интерпретирует интерполированную переменную, и я попытался сделать это так:

print "|",$string_copy,"|\n";

но я все еще получаю только ведущую трубу. Это заставляет меня думать, что со строкой действительно что-то не так. Я не могу думать ни о чем другом.

Ответы [ 4 ]

2 голосов
/ 10 июня 2010

Начало .* не имеет смысла, как и модификатор /i.

Если строка заканчивается новой строкой, то ей будет соответствовать \s+.Поскольку следующий (.*) ничего не может найти, совпадение будет успешным, но $1 будет пустым.Вместо этого заставьте его соответствовать чему-либо: /(\S+)"$/

2 голосов
/ 10 июня 2010
my $string = '/Od /D "WIN32" /D "_DEBUG" /FD /EHa /MDd /Fo"Debug" /Fd"Debug\vc80.pdb" /W3 /c /Zi /clr /TP .\main.cpp"';
if($string =~ /.*\s+(.*)$/i) {
    print "matched ",$1,"\n";
}

Это работает для меня и печатает matched .\main.cpp".

Пожалуйста, покажите, как вы настраиваете $string. Возможно, вы как-то напутали с цитатами или чем-то в этом роде.

РЕДАКТИРОВАТЬ : Возможно, у вас есть символ \x0d в конце вашей строки? Вы не заметите это в журнале, когда напечатаете вашу строку, и chomp не удалит ее:

my $string = '/Od /D "WIN32" /D "_DEBUG" /FD /EHa /MDd /Fo"Debug" /Fd"Debug\vc80.pdb" /W3 /c /Zi /clr /TP .\main.cpp"' . "\x0d";
chomp $string;
if($string =~ /.*\s+(.*)$/i) {
    print "matched ",$1,"\n";
}

Это печатает matched для меня, без захвата имени файла. Может быть, это ваш случай?

C:\>perl --version

This is perl, v5.10.1 built for MSWin32-x64-multi-thread
1 голос
/ 10 июня 2010

Похоже, все, что вы на самом деле хотите, это

$string =~ /(\S+)$/
0 голосов
/ 10 июня 2010

Попробуйте это:

#!/usr/bin/perl

$string = <STDIN>;
chomp($string);
print $string;

if($string =~ /.*\s+(.*)$/) {
  print "\nmatched ",$1,"\n";
}

Это perl, v5.8.8, созданный для i486-linux-gnu-thread-multi

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