开发者

How can I make this Perl regex work?

开发者 https://www.devze.com 2023-01-03 05:18 出处:网络
I have this line /Od /D \"WIN32\" /D \"_DEBUG\" /FD /EHa /MDd /Fo\"Debug\" /Fd\"Debug\\vc80.pdb\" /W3 /c /Zi /clr /TP .\\main.cpp\"

I have this line

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

And I want to extract the .\main.cpp. I thought the following would do the trick:

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

because this same regex works in Ruby, and extracts the string I required. How can I get it working?

EDIT: here's how I setup my string:

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

find_indexes returns the indexes of lines matching any of the parameter following the array ref. The modify sub will return a modified version of the string sent to it, containing some additional defines.

EDIT2: here's the modify sub:

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";
    }
}

The sub isn't complete, as I wasn't able to get it to work the way it should. I added an extra quote in the capturing group to force it to match the name. Someth开发者_运维技巧ing strange's happening though, I would expect the print of the $string_copy to print the original string surrounded in |. However, I only get the leading pipe, not the ending one. I thought maybe Perl is interpreting the interpolated variable wrong, and I tried to do it like this:

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

but I still only get a leading pipe. This leads me to think something may indeed be wrong with the string. I can't think of anything else.


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";
}

This works for me and prints matched .\main.cpp".

Please show how do you set up $string. It's possible that you somehow messed up with quotes or something.

EDIT: Is it possible that you have \x0d symbol at the end of your string? You would not notice it in log when you print your string and chomp won't remove it:

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";
}

This prints matched for me, without capturing the file name. Maybe that's your case?

C:\>perl --version

This is perl, v5.10.1 built for MSWin32-x64-multi-thread


The leading .* is meaningless, as is the /i modifier.

If the string ends in a newline, that will be matched by the \s+. Since the (.*) that follows can match nothing, the match will succeed but $1 will be empty. Instead, force it to match something: /(\S+)"$/


It looks like all you actually want is

$string =~ /(\S+)$/


Try this:

#!/usr/bin/perl

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

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

This is perl, v5.8.8 built for i486-linux-gnu-thread-multi

0

精彩评论

暂无评论...
验证码 换一张
取 消