in reply to Re: string manipulation
in thread string manipulation


Thanks.

Another question in the same issue: I have the following initialization
CPP_PROJ=/nologo /MDd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "_LIB" /D "_F +P_BKLIB" /D "_MBCS" /D "FTLIB" /D "_AFXDLL" /D "WIN32" /FR"$(I NTDIR)\\" /Fp"$(INTDIR)\ApplicationObject.pch" /YX /Fo"$(INTDIR)\\" /F +d"$(INTDIR)\\" /FD /GZ /c

I need to match all the strings start with /D "_<any_string" to variable and replace "/D" with "-D" so finally the new variable should to be like:
$NEW_VAR = "-D_ DEBUG -D_LIB -D_FP_BKLIB -D_MBCS - DFTLIB …"
Please advice. Thanks again

Replies are listed 'Best First'.
Re^3: string manipulation
by tachyon-II (Chaplain) on May 18, 2008 at 12:59 UTC
    (my @d) = $str =~ m!/D\s+"([^"]+)"!g; my $var = join " ", map{"-D$_"}@d;

      Last Question :-) I open file to read and should retrevie all the lines start with " SOURCE=.\" as display below:
      SOURCE=.\ApplicationObject.cpp SOURCE=.\BusinessObject.cpp SOURCE=.\ClientObject.cpp SOURCE=.\ComponentServer.cpp SOURCE=.\main.cpp SOURCE=.\posix_timer.cpp SOURCE=.\ServiceServer.cpp SOURCE=.\SystemObject.cpp SOURCE=.\TestProgram.cpp SOURCE=.\workflow.cpp

      I need to initialize variable only with the file name, so finally I should have:
      $fileLst=" ApplicationObject.cpp BusinessObject.cpp ClientObject.cpp ComponentServer.cpp" My current code is:
      foreach my $line (<MAKFILE>) { chomp $line; if ($line =~ m/SOURCE=\.\\(.*)$/i) { push @fileLst, $1; } } close MAKFILE; $fileLst = join " ", @fileLst; return $fileLst;

      The final result includes garbage: "workflow.cppcppppppp".
      Please advice. Thanks.
        foreach my $line (<MAKFILE>) {

        I personally believe you should know that almost always in Perl (5) the Right™ way to iterate over the lines of a file is a while loop. You should also be using lexical filehandles.

        if ($line =~ m/SOURCE=\.\\(.*)$/i) {

        I generally chomp too, but incidentally $ matches right before \n too; you may also push the return value of the match operator.

        $fileLst = join " ", @fileLst;

        Perhaps you prefer to be explicit, and I'm sure many people would say that you're right, but there's a very convenient shortcut for join " ", @fileLst, which is "@fileLst"; also, I see no reason to create an intermediate temporary variable just to return it.

        All in all, I will give you an example subroutine which will accept a filename and give you your expected output:

        sub domkfile { my ($fname, @flist)=shift; open my $fh, '<', $fname or die "Can't open `$fname': $!\n"; push @flist, /SOURCE=\.\\(.*)$/i while <$fh>; "@flist"; }

        If slurping the whole file at once is not a problem, and indeed it should not be in this case, you may avoid the use of the @flist array with a map:

        sub domkfile { my $fname=shift; open my $fh, '<', $fname or die "Can't open `$fname': $!\n"; join ' ' => map /SOURCE=\.\\(.*)$/i, <$fh>; }
        --
        If you can't understand the incipit, then please check the IPB Campaign.