in reply to Re: regex basics
in thread regex basics

Hi CountZero and thanks for the reply.

I tried this (using CentOS 6.6):

#!/usr/bin/env perl use Modern::Perl qw /2014/; my $iniprod = 'php.ini-production'; my $ininocm = 'php.ini-nocomments'; open my $IN, '<', $iniprod or die "Could not open $iniprod for readin +g: $!"; open my $OUT, '>', $ininocm or die "Could not open $ininocm for writin +g: $!"; while (<$IN>) { print $OUT $_ unless /;\s+/ ; } close $IN or die "Error closing $iniprod: $!"; close $OUT or die "Error closing $ininocm: $!";
results:
[/etc/php.d] # ./php.ini-remove-comments.pl Can't locate Modern/Perl.pm in @INC (@INC contains: /usr/local/lib64/p +erl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/p +erl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at ./php.ini-re +move-comments.pl line 2. BEGIN failed--compilation aborted at ./php.ini-remove-comments.pl line + 2.
I checked...
[/etc/php.d] # perl -v This is perl, v5.10.1 (*) built for x86_64-linux-thread-multi

The release date for 5.10.1 was 2009-Aug-06. Apparently a lot has changed in 5 years... latest version at 5.21.3?

I commented 'use Modern::Perl qw /2014/;' and it worked perfectly--except it left blank lines like tombstones where the comments used to be.

I thought another pass would do it:
1 #!/usr/bin/env perl 2 # use Modern::Perl qw /2014/; 3 4 my $iniprod = 'php.ini-production'; 5 my $ininocm = 'php.ini-nocomments'; 6 7 open my $IN, '<', $iniprod or die "Could not open $iniprod fo +r reading: $!"; 8 open my $OUT, '>', $ininocm or die "Could not open $ininocm fo +r writing: $!"; 9 10 while (<$IN>) { 11 print $OUT $_ unless /;\s+/; 12 } 13 while (<$OUT>) { 14 print $OUT $_ unless /\n+/; 15 } 16 close $IN or die "Error closing $iniprod: $!"; 17 close $OUT or die "Error closing $ininocm: $!"; 18
did not work. I tried to come up with something like this...
#!/usr/bin/env perl # use Modern::Perl qw /2014/; my $iniprod = 'php.ini-production'; my $ininocm = 'php.ini-nocomments'; open my $IN, '<', $iniprod or die "Could not open $iniprod for readin +g: $!"; open my $OUT, '>', $ininocm or die "Could not open $ininocm for writin +g: $!"; while (<$IN>) { if (!$_ /;\s+/) { print $OUT $_ } } close $IN or die "Error closing $iniprod: $!"; close $OUT or die "Error closing $ininocm: $!";

but I'm getting an error...

Substitution pattern not terminated

Is this any different form 'print OUT $_ unless...' ?

Should I use chomp here?

Replies are listed 'Best First'.
Re^3: regex basics
by poj (Abbot) on Feb 01, 2015 at 13:29 UTC
    Try
    #!/usr/bin/env perl use strict; use warnings; my $iniprod = 'php.ini-production'; my $ininocm = 'php.ini-nocomments'; my $log = 'removed.log'; open my $IN, '<', $iniprod or die "Could not open $iniprod for reading: $!"; open my $LOG, '>', $log or die "Could not open $log for writing: $!"; my $count=0; my $text; while (<$IN>) { ++$count; if (/;\s+/) { print $LOG "$count : $_"; } else { $text .= $_; } } close $IN or die "Error closing $iniprod: $!"; # squash multiple blank lines to one $text =~ s{\n{3,}}{\n\n}gm; open my $OUT, '>', $ininocm or die "Could not open $ininocm for writing: $!"; print $OUT $text; close $OUT or die "Error closing $ininocm: $!"; __DATA__ line 1 ; this directive does such and such ; and some more ;some_directive line 2 line 3 line 4 line 5
    poj

      Thanks! That worked perfectly. The only change I made was to remove the log. the original file remains intact for reference so a log really isn't necessary.

      while (<$IN>) { if (!/;\s+/) { $text .= $_; } } ... $text =~ s{\n{2,}}{\n}gm;$

      Interestingly, this is what I was reaching for. I was thinking "two passes" were needed... but the file was already open. So dump only lines of interest into a string and use a second regex operation to remove blank lines.

      I like the use of curly braces for search/replace--easier to read. But I'll need to take a closer look at the .= operator (I assume it's similar to += in C#)

Re^3: regex basics
by CountZero (Bishop) on Feb 02, 2015 at 13:12 UTC
    Modern::Perl is indeed for more recent versions of Perl. I'm running Perl 5.18. You can safely delete it in this script and add use strict; use warnings; in its place.

    Those blank lines you see are mysterious. There shouldn't be any such lines as nothing is printed when a comment is found.

    !$_ /;\s+/ is invalid syntax and confused the Perl-interpreter hence the rather unhelpful error message.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics

      CountZero, did you say !$_ /;\s+/ is invalid syntax?

      And here I was all ready to use this on other config files. If fact, I already have:

      #!/usr/bin/env perl use strict; use warnings; my $conforig = 'httpd.conf-orig'; my $confnocm = 'httpd.conf-nocomments'; open my $IN, '<', $conforig or die "Could not open $conforig for reading: $!"; my $text; while (<$IN>) { if (!/\#\s+/) { $text .= $_; } } close $IN or die "Error closing $conforig: $!"; # remove blank lines $text =~ s{\n{2,}}{\n}gm; open my $OUT, '>', $confnocm or die "Could not open $confnocm for writing: $!"; print $OUT $text; close $OUT or die "Error closing $confnocm: $!";
      It seems to work... but please show me the correct negation syntax before the code police smash in my door, drag me off to a detention camp and force me to write JavaScript.
        These are not the same:
        !$_ /;\s+/ !/\#\s+/

        In fact, when you want to mention the thing to be matched, you must use the binding operator:

        !( $_ =~ /;\s+/); # or $_ !~ /;\s+/;

        Update: Precedence fixed. Thanks AnomalousMonk.

        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ